Merge pull request #11 from electron/master

update as upstream
This commit is contained in:
Heilig Benedek 2016-06-21 00:08:48 +02:00 committed by GitHub
commit a35915ee9f
244 changed files with 2853 additions and 1542 deletions

View file

@ -68,7 +68,7 @@
* :non-potable_water: `:non-potable_water:` 메모리 누수를 연결했을 때
* :memo: `:memo:` 문서를 작성했을 때
* :penguin: `:penguin:` Linux에 대한 패치를 했을 때
* :apple: `:apple:` Mac OS에 대한 패치를 했을 때
* :apple: `:apple:` macOS에 대한 패치를 했을 때
* :checkered_flag: `:checkered_flag:` Windows에 대한 패치를 했을 때
* :bug: `:bug:` 버그를 고쳤을 때
* :fire: `:fire:` 코드 또는 파일을 삭제했을 때

View file

@ -65,7 +65,7 @@ possible with your report. If you can, please include:
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
* :penguin: `:penguin:` when fixing something on Linux
* :apple: `:apple:` when fixing something on Mac OS
* :apple: `:apple:` when fixing something on macOS
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
* :bug: `:bug:` when fixing a bug
* :fire: `:fire:` when removing code or files

View file

@ -8,10 +8,10 @@
### [Electron](https://github.com/electron/electron/) 한국어 참조 문서
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여
Cross-Platform 데스크톱 플리케이션을 개발할 수 있도록 해주는 프레임워크입니다.
Cross-Platform 데스크톱 플리케이션을 개발할 수 있도록 해주는 프레임워크입니다.
[Node.js](https://nodejs.org/)와 [Chromium](http://www.chromium.org)을 기반으로
만들어졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
더 많은 플리케이션은 [이곳](http://electron.atom.io/apps)에서 확인하세요.
더 많은 플리케이션은 [이곳](http://electron.atom.io/apps)에서 확인하세요.
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서
[@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
@ -22,7 +22,7 @@ Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서
## 다운로드
Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어
Linux, Windows, macOS 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어
있습니다. [releases](https://github.com/electron/electron/releases) 페이지에서
받아 볼 수 있습니다.
@ -77,4 +77,4 @@ npm install electron-prebuilt --save-dev
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
커뮤니티가 운영중인 유용한 예시 플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다.
커뮤니티가 운영중인 유용한 예시 플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다.

View file

@ -19,7 +19,7 @@ behavior to electron@github.com.
## Downloads
Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can
Prebuilt binaries and debug symbols of Electron for Linux, Windows and macOS can
be found on the [releases](https://github.com/electron/electron/releases) page.
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron

View file

@ -79,6 +79,12 @@ void AutoUpdater::OnWindowAllClosed() {
QuitAndInstall();
}
void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
auto_updater::AutoUpdater::HeaderMap headers;
args->GetNext(&headers);
auto_updater::AutoUpdater::SetFeedURL(url, headers);
}
void AutoUpdater::QuitAndInstall() {
// If we don't have any window then quitAndInstall immediately.
WindowList* window_list = WindowList::GetInstance();
@ -102,8 +108,8 @@ mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
void AutoUpdater::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}

View file

@ -10,6 +10,7 @@
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/auto_updater.h"
#include "atom/browser/window_list_observer.h"
#include "native_mate/arguments.h"
#include "native_mate/handle.h"
namespace atom {
@ -43,6 +44,7 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
void OnWindowAllClosed() override;
private:
void SetFeedURL(const std::string& url, mate::Arguments* args);
void QuitAndInstall();
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);

View file

@ -19,7 +19,7 @@ class MenuMac : public Menu {
protected:
explicit MenuMac(v8::Isolate* isolate);
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
void PopupAt(Window* window, int x, int y, int positioning_item) override;
base::scoped_nsobject<AtomMenuController> menu_controller_;

View file

@ -17,7 +17,7 @@ class MenuViews : public Menu {
explicit MenuViews(v8::Isolate* isolate);
protected:
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
void PopupAt(Window* window, int x, int y, int positioning_item) override;
private:
DISALLOW_COPY_AND_ASSIGN(MenuViews);

View file

@ -5,7 +5,6 @@
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/net/url_request_async_asar_job.h"
#include "atom/browser/net/url_request_buffer_job.h"
@ -28,9 +27,9 @@ namespace atom {
namespace api {
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()),
job_factory_(browser_context->job_factory()) {
CHECK(job_factory_);
: request_context_getter_(static_cast<brightray::URLRequestContextGetter*>(
browser_context->GetRequestContext())),
weak_factory_(this) {
Init(isolate);
}
@ -46,30 +45,37 @@ void Protocol::UnregisterProtocol(
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
base::Unretained(this), scheme),
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
GetWeakPtr(), callback));
}
// static
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
if (!job_factory_->HasProtocolHandler(scheme))
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (!job_factory->HasProtocolHandler(scheme))
return PROTOCOL_NOT_REGISTERED;
job_factory_->SetProtocolHandler(scheme, nullptr);
job_factory->SetProtocolHandler(scheme, nullptr);
return PROTOCOL_OK;
}
void Protocol::IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback) {
const BooleanCallback& callback) {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO,
base::Unretained(this), scheme),
request_context_getter_, scheme),
callback);
}
bool Protocol::IsProtocolHandledInIO(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
// static
bool Protocol::IsProtocolHandledInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
}
void Protocol::UninterceptProtocol(
@ -79,18 +85,18 @@ void Protocol::UninterceptProtocol(
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UninterceptProtocolInIO,
base::Unretained(this), scheme),
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
GetWeakPtr(), callback));
}
// static
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
if (!original_protocols_.contains(scheme))
return PROTOCOL_NOT_INTERCEPTED;
job_factory_->ReplaceProtocol(scheme,
original_protocols_.take_and_erase(scheme));
return PROTOCOL_OK;
return static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory())->UninterceptProtocol(scheme) ?
PROTOCOL_OK : PROTOCOL_NOT_INTERCEPTED;
}
void Protocol::OnIOCompleted(
@ -121,6 +127,13 @@ std::string Protocol::ErrorCodeToString(ProtocolError error) {
}
}
AtomURLRequestJobFactory* Protocol::GetJobFactoryInIO() const {
request_context_getter_->GetURLRequestContext(); // Force init.
return static_cast<AtomURLRequestJobFactory*>(
static_cast<brightray::URLRequestContextGetter*>(
request_context_getter_.get())->job_factory());
}
// static
mate::Handle<Protocol> Protocol::Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context) {

View file

@ -10,28 +10,22 @@
#include <vector>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/callback.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/url_request/url_request_context.h"
namespace base {
class DictionaryValue;
}
namespace net {
class URLRequest;
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
class AtomURLRequestJobFactory;
namespace api {
class Protocol : public mate::TrackableObject<Protocol> {
@ -80,13 +74,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
return request_job;
}
private:
v8::Isolate* isolate_;
net::URLRequestContextGetter* request_context_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
Protocol::Handler handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
@ -105,19 +99,24 @@ class Protocol : public mate::TrackableObject<Protocol> {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
base::Unretained(this), scheme, handler),
request_context_getter_, isolate(), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
GetWeakPtr(), callback));
}
template<typename RequestJob>
ProtocolError RegisterProtocolInIO(const std::string& scheme,
const Handler& handler) {
if (job_factory_->IsHandledProtocol(scheme))
static ProtocolError RegisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (job_factory->IsHandledProtocol(scheme))
return PROTOCOL_REGISTERED;
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate(), request_context_getter_, handler));
if (job_factory_->SetProtocolHandler(scheme, std::move(protocol_handler)))
isolate, request_context_getter.get(), handler));
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
return PROTOCOL_OK;
else
return PROTOCOL_FAIL;
@ -125,12 +124,16 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Unregister the protocol handler that handles |scheme|.
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
ProtocolError UnregisterProtocolInIO(const std::string& scheme);
static ProtocolError UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Whether the protocol has handler registered.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
bool IsProtocolHandledInIO(const std::string& scheme);
static bool IsProtocolHandledInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Replace the protocol handler with a new one.
template<typename RequestJob>
@ -142,32 +145,36 @@ class Protocol : public mate::TrackableObject<Protocol> {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
base::Unretained(this), scheme, handler),
request_context_getter_, isolate(), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
GetWeakPtr(), callback));
}
template<typename RequestJob>
ProtocolError InterceptProtocolInIO(const std::string& scheme,
const Handler& handler) {
if (!job_factory_->IsHandledProtocol(scheme))
static ProtocolError InterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (!job_factory->IsHandledProtocol(scheme))
return PROTOCOL_NOT_REGISTERED;
// It is possible a protocol is handled but can not be intercepted.
if (!job_factory_->HasProtocolHandler(scheme))
if (!job_factory->HasProtocolHandler(scheme))
return PROTOCOL_FAIL;
if (ContainsKey(original_protocols_, scheme))
return PROTOCOL_INTERCEPTED;
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate(), request_context_getter_, handler));
original_protocols_.set(
scheme,
job_factory_->ReplaceProtocol(scheme, std::move(protocol_handler)));
isolate, request_context_getter.get(), handler));
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
return PROTOCOL_INTERCEPTED;
return PROTOCOL_OK;
}
// Restore the |scheme| to its original protocol handler.
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
ProtocolError UninterceptProtocolInIO(const std::string& scheme);
static ProtocolError UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
// Convert error code to JS exception and call the callback.
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
@ -175,15 +182,14 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Convert error code to string.
std::string ErrorCodeToString(ProtocolError error);
net::URLRequestContextGetter* request_context_getter_;
AtomURLRequestJobFactory* GetJobFactoryInIO() const;
// Map that stores the original protocols of schemes.
using OriginalProtocolsMap = base::ScopedPtrHashMap<
std::string,
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>>;
OriginalProtocolsMap original_protocols_;
base::WeakPtr<Protocol> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
AtomURLRequestJobFactory* job_factory_; // weak ref
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter_;
base::WeakPtrFactory<Protocol> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Protocol);
};

View file

@ -4,9 +4,8 @@
#include "atom/browser/api/atom_api_render_process_preferences.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/native_window.h"
#include "atom/browser/window_list.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "content/public/browser/render_process_host.h"
@ -19,18 +18,17 @@ namespace api {
namespace {
bool IsBrowserWindow(content::RenderProcessHost* process) {
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
content::WebContents* web_contents =
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->
GetWebContentsFromProcessID(process->GetID());
if (!web_contents)
return false;
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
if (!window)
return false;
return true;
auto api_web_contents = WebContents::CreateFrom(isolate, web_contents);
auto type = api_web_contents->GetType();
return type == WebContents::Type::BROWSER_WINDOW ||
type == WebContents::Type::WEB_VIEW;
}
} // namespace
@ -63,10 +61,11 @@ void RenderProcessPreferences::BuildPrototype(
// static
mate::Handle<RenderProcessPreferences>
RenderProcessPreferences::ForAllBrowserWindow(v8::Isolate* isolate) {
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
return mate::CreateHandle(
isolate,
new RenderProcessPreferences(isolate, base::Bind(&IsBrowserWindow)));
new RenderProcessPreferences(isolate,
base::Bind(&IsWebContents, isolate)));
}
} // namespace api
@ -78,8 +77,8 @@ namespace {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("forAllBrowserWindow",
&atom::api::RenderProcessPreferences::ForAllBrowserWindow);
dict.SetMethod("forAllWebContents",
&atom::api::RenderProcessPreferences::ForAllWebContents);
}
} // namespace

View file

@ -17,7 +17,7 @@ class RenderProcessPreferences
: public mate::Wrappable<RenderProcessPreferences> {
public:
static mate::Handle<RenderProcessPreferences>
ForAllBrowserWindow(v8::Isolate* isolate);
ForAllWebContents(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);

View file

@ -187,6 +187,39 @@ struct Converter<content::SavePageType> {
}
};
template<>
struct Converter<atom::api::WebContents::Type> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
atom::api::WebContents::Type val) {
using Type = atom::api::WebContents::Type;
std::string type = "";
switch (val) {
case Type::BACKGROUND_PAGE: type = "backgroundPage"; break;
case Type::BROWSER_WINDOW: type = "window"; break;
case Type::REMOTE: type = "remote"; break;
case Type::WEB_VIEW: type = "webview"; break;
default: break;
}
return mate::ConvertToV8(isolate, type);
}
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::api::WebContents::Type* out) {
using Type = atom::api::WebContents::Type;
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "webview") {
*out = Type::WEB_VIEW;
} else if (type == "backgroundPage") {
*out = Type::BACKGROUND_PAGE;
} else {
return false;
}
return true;
}
};
} // namespace mate
@ -233,15 +266,22 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate,
const mate::Dictionary& options)
: embedder_(nullptr),
type_(BROWSER_WINDOW),
request_id_(0),
background_throttling_(true) {
// Read options.
options.Get("backgroundThrottling", &background_throttling_);
// Whether it is a guest WebContents.
bool is_guest = false;
options.Get("isGuest", &is_guest);
type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW;
// FIXME(zcbenz): We should read "type" parameter for better design, but
// on Windows we have encountered a compiler bug that if we read "type"
// from |options| and then set |type_|, a memory corruption will happen
// and Electron will soon crash.
// Remvoe this after we upgraded to use VS 2015 Update 3.
bool b = false;
if (options.Get("isGuest", &b) && b)
type_ = WEB_VIEW;
else if (options.Get("isBackgroundPage", &b) && b)
type_ = BACKGROUND_PAGE;
// Obtain the session.
std::string partition;
@ -261,7 +301,7 @@ WebContents::WebContents(v8::Isolate* isolate,
session_.Reset(isolate, session.ToV8());
content::WebContents* web_contents;
if (is_guest) {
if (IsGuest()) {
scoped_refptr<content::SiteInstance> site_instance =
content::SiteInstance::CreateForURL(
session->browser_context(), GURL("chrome-guest://fake-host"));
@ -290,7 +330,7 @@ WebContents::WebContents(v8::Isolate* isolate,
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
if (is_guest) {
if (IsGuest()) {
guest_delegate_->Initialize(this);
NativeWindow* owner_window = nullptr;
@ -744,13 +784,8 @@ int WebContents::GetID() const {
return web_contents()->GetRenderProcessHost()->GetID();
}
std::string WebContents::GetType() const {
switch (type_) {
case BROWSER_WINDOW: return "window";
case WEB_VIEW: return "webview";
case REMOTE: return "remote";
default: return "";
}
WebContents::Type WebContents::GetType() const {
return type_;
}
bool WebContents::Equal(const WebContents* web_contents) const {

View file

@ -43,6 +43,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
public CommonWebContentsDelegate,
public content::WebContentsObserver {
public:
enum Type {
BACKGROUND_PAGE, // A DevTools extension background page.
BROWSER_WINDOW, // Used by BrowserWindow.
REMOTE, // Thin wrap around an existing WebContents.
WEB_VIEW, // Used by <webview>.
};
// For node.js callback function type: function(error, buffer)
using PrintToPDFCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
@ -59,7 +66,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
v8::Local<v8::ObjectTemplate> prototype);
int GetID() const;
std::string GetType() const;
Type GetType() const;
bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url);
@ -268,12 +275,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DevToolsClosed() override;
private:
enum Type {
BROWSER_WINDOW, // Used by BrowserWindow.
WEB_VIEW, // Used by <webview>.
REMOTE, // Thin wrap around an existing WebContents.
};
AtomBrowserContext* GetBrowserContext() const;
uint32_t GetNextRequestId() {

View file

@ -95,9 +95,16 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
"browserWindowOptions", options);
// The parent window.
mate::Handle<Window> parent;
if (options.Get("parent", &parent))
parent_window_.Reset(isolate, parent.ToV8());
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
window_.reset(NativeWindow::Create(
web_contents->managed_web_contents(),
options,
parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
@ -120,10 +127,32 @@ Window::~Window() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
}
void Window::AfterInit(v8::Isolate* isolate) {
mate::TrackableObject<Window>::AfterInit(isolate);
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
mate::Handle<Window> parent;
if (!parent_window_.IsEmpty() &&
mate::ConvertFromV8(isolate, GetParentWindow(), &parent))
parent->child_windows_.Set(isolate, ID(), GetWrapper());
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void Window::WillDestoryNativeObject() {
// Close all child windows before closing current window.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
mate::Handle<Window> child;
if (mate::ConvertFromV8(isolate(), value, &child))
child->window_->CloseImmediately();
}
}
void Window::OnWindowClosed() {
api_web_contents_->DestroyWebContents();
@ -136,6 +165,8 @@ void Window::OnWindowClosed() {
Emit("closed");
RemoveFromParentChildWindows();
// Destroy the native class when window is closed.
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
}
@ -156,6 +187,10 @@ void Window::OnWindowHide() {
Emit("hide");
}
void Window::OnReadyToShow() {
Emit("ready-to-show");
}
void Window::OnWindowMaximize() {
Emit("maximize");
}
@ -276,6 +311,10 @@ void Window::Show() {
}
void Window::ShowInactive() {
// This method doesn't make sense for modal window..
if (IsModal())
return;
window_->ShowInactive();
}
@ -287,6 +326,10 @@ bool Window::IsVisible() {
return window_->IsVisible();
}
bool Window::IsEnabled() {
return window_->IsEnabled();
}
void Window::Maximize() {
window_->Maximize();
}
@ -529,6 +572,10 @@ void Window::SetIgnoreMouseEvents(bool ignore) {
return window_->SetIgnoreMouseEvents(ignore);
}
void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(const gfx::Image&)> callback;
@ -642,6 +689,42 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
window_->SetAspectRatio(aspect_ratio, extra_size);
}
void Window::SetParentWindow(v8::Local<v8::Value> value,
mate::Arguments* args) {
if (IsModal()) {
args->ThrowError("Can not be called for modal window");
return;
}
mate::Handle<Window> parent;
if (value->IsNull()) {
RemoveFromParentChildWindows();
parent_window_.Reset();
window_->SetParentWindow(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &parent)) {
parent_window_.Reset(isolate(), value);
window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), ID(), GetWrapper());
} else {
args->ThrowError("Must pass BrowserWindow instance or null");
}
}
v8::Local<v8::Value> Window::GetParentWindow() const {
if (parent_window_.IsEmpty())
return v8::Null(isolate());
else
return v8::Local<v8::Value>::New(isolate(), parent_window_);
}
std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
return child_windows_.Values(isolate());
}
bool Window::IsModal() const {
return window_->is_modal();
}
v8::Local<v8::Value> Window::GetNativeWindowHandle() {
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
return ToBuffer(
@ -667,6 +750,17 @@ v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
void Window::RemoveFromParentChildWindows() {
if (parent_window_.IsEmpty())
return;
mate::Handle<Window> parent;
if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent))
return;
parent->child_windows_.Remove(ID());
}
// static
void Window::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype) {
@ -680,6 +774,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("showInactive", &Window::ShowInactive)
.SetMethod("hide", &Window::Hide)
.SetMethod("isVisible", &Window::IsVisible)
.SetMethod("isEnabled", &Window::IsEnabled)
.SetMethod("maximize", &Window::Maximize)
.SetMethod("unmaximize", &Window::Unmaximize)
.SetMethod("isMaximized", &Window::IsMaximized)
@ -689,6 +784,12 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setFullScreen", &Window::SetFullScreen)
.SetMethod("isFullScreen", &Window::IsFullscreen)
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
#if !defined(OS_WIN)
.SetMethod("setParentWindow", &Window::SetParentWindow)
#endif
.SetMethod("getParentWindow", &Window::GetParentWindow)
.SetMethod("getChildWindows", &Window::GetChildWindows)
.SetMethod("isModal", &Window::IsModal)
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
.SetMethod("getBounds", &Window::GetBounds)
.SetMethod("setBounds", &Window::SetBounds)
@ -732,6 +833,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
.SetMethod("setFocusable", &Window::SetFocusable)
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)

View file

@ -6,15 +6,16 @@
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_window.h"
#include "atom/browser/native_window_observer.h"
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/key_weak_map.h"
#include "native_mate/handle.h"
class GURL;
@ -54,13 +55,18 @@ class Window : public mate::TrackableObject<Window>,
Window(v8::Isolate* isolate, const mate::Dictionary& options);
~Window() override;
// TrackableObject:
void AfterInit(v8::Isolate* isolate) override;
// NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override;
void WillDestoryNativeObject() override;
void OnWindowClosed() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
void OnWindowShow() override;
void OnWindowHide() override;
void OnReadyToShow() override;
void OnWindowMaximize() override;
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;
@ -93,6 +99,7 @@ class Window : public mate::TrackableObject<Window>,
void ShowInactive();
void Hide();
bool IsVisible();
bool IsEnabled();
void Maximize();
void Unmaximize();
bool IsMaximized();
@ -146,6 +153,7 @@ class Window : public mate::TrackableObject<Window>,
void SetDocumentEdited(bool edited);
bool IsDocumentEdited();
void SetIgnoreMouseEvents(bool ignore);
void SetFocusable(bool focusable);
void CapturePage(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
@ -157,6 +165,10 @@ class Window : public mate::TrackableObject<Window>,
void SetMenuBarVisibility(bool visible);
bool IsMenuBarVisible();
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
v8::Local<v8::Value> GetParentWindow() const;
std::vector<v8::Local<v8::Object>> GetChildWindows() const;
bool IsModal() const;
v8::Local<v8::Value> GetNativeWindowHandle();
#if defined(OS_WIN)
@ -179,6 +191,9 @@ class Window : public mate::TrackableObject<Window>,
int32_t ID() const;
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
// Remove this window from parent window's |child_windows_|.
void RemoveFromParentChildWindows();
#if defined(OS_WIN)
typedef std::map<UINT, MessageCallback> MessageCallbackMap;
MessageCallbackMap messages_callback_map_;
@ -186,6 +201,8 @@ class Window : public mate::TrackableObject<Window>,
v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> menu_;
v8::Global<v8::Value> parent_window_;
KeyWeakMap<int> child_windows_;
api::WebContents* api_web_contents_;

View file

@ -20,14 +20,15 @@
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "components/prefs/pref_registry_simple.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
@ -66,7 +67,6 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory)
: brightray::BrowserContext(partition, in_memory),
cert_verifier_(new AtomCertVerifier),
job_factory_(new AtomURLRequestJobFactory),
network_delegate_(new AtomNetworkDelegate) {
}
@ -96,15 +96,15 @@ std::string AtomBrowserContext::GetUserAgent() {
std::unique_ptr<net::URLRequestJobFactory>
AtomBrowserContext::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
content::URLRequestInterceptorScopedVector* interceptors) {
std::unique_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
content::ProtocolHandlerMap* protocol_handlers) {
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
new AtomURLRequestJobFactory);
for (auto& it : *handlers) {
for (auto& it : *protocol_handlers) {
job_factory->SetProtocolHandler(it.first,
make_scoped_ptr(it.second.release()));
base::WrapUnique(it.second.release()));
}
handlers->clear();
protocol_handlers->clear();
job_factory->SetProtocolHandler(
url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler));
@ -132,16 +132,7 @@ AtomBrowserContext::CreateURLRequestJobFactory(
make_scoped_ptr(new net::FtpProtocolHandler(
new net::FtpNetworkLayer(host_resolver))));
// Set up interceptors in the reverse order.
std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
std::move(job_factory);
content::URLRequestInterceptorScopedVector::reverse_iterator it;
for (it = interceptors->rbegin(); it != interceptors->rend(); ++it)
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
std::move(top_job_factory), make_scoped_ptr(*it)));
interceptors->weak_clear();
return top_job_factory;
return std::move(job_factory);
}
net::HttpCache::BackendFactory*

View file

@ -15,7 +15,6 @@ class AtomDownloadManagerDelegate;
class AtomCertVerifier;
class AtomNetworkDelegate;
class AtomPermissionManager;
class AtomURLRequestJobFactory;
class WebViewManager;
class AtomBrowserContext : public brightray::BrowserContext {
@ -27,8 +26,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
net::NetworkDelegate* CreateNetworkDelegate() override;
std::string GetUserAgent() override;
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
content::URLRequestInterceptorScopedVector* interceptors) override;
content::ProtocolHandlerMap* protocol_handlers) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier() override;
@ -43,9 +41,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
AtomCertVerifier* cert_verifier() const { return cert_verifier_; }
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
private:
@ -55,7 +50,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
// Managed by brightray::BrowserContext.
AtomCertVerifier* cert_verifier_;
AtomURLRequestJobFactory* job_factory_;
AtomNetworkDelegate* network_delegate_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);

View file

@ -148,7 +148,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
#endif
#if !defined(OS_MACOSX)
// The corresponding call in OS X is in AtomApplicationDelegate.
// The corresponding call in macOS is in AtomApplicationDelegate.
Browser::Get()->WillFinishLaunching();
Browser::Get()->DidFinishLaunching();
#endif

View file

@ -17,7 +17,8 @@ void AutoUpdater::SetDelegate(Delegate* delegate) {
}
#if !defined(OS_MACOSX) || defined(MAS_BUILD)
void AutoUpdater::SetFeedURL(const std::string& url) {
void AutoUpdater::SetFeedURL(const std::string& url,
const HeaderMap& requestHeaders) {
}
void AutoUpdater::CheckForUpdates() {

View file

@ -5,6 +5,7 @@
#ifndef ATOM_BROWSER_AUTO_UPDATER_H_
#define ATOM_BROWSER_AUTO_UPDATER_H_
#include <map>
#include <string>
#include "base/macros.h"
@ -42,11 +43,14 @@ class Delegate {
class AutoUpdater {
public:
typedef std::map<std::string, std::string> HeaderMap;
// Gets/Sets the delegate.
static Delegate* GetDelegate();
static void SetDelegate(Delegate* delegate);
static void SetFeedURL(const std::string& url);
static void SetFeedURL(const std::string& url,
const HeaderMap& requestHeaders);
static void CheckForUpdates();
static void QuitAndInstall();

View file

@ -29,35 +29,42 @@ bool g_update_available = false;
}
// static
void AutoUpdater::SetFeedURL(const std::string& feed) {
if (g_updater == nil) {
Delegate* delegate = GetDelegate();
if (!delegate)
return;
void AutoUpdater::SetFeedURL(const std::string& feed,
const HeaderMap& requestHeaders) {
Delegate* delegate = GetDelegate();
if (!delegate)
return;
// Initialize the SQRLUpdater.
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
@try {
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
} @catch (NSException* error) {
delegate->OnError(base::SysNSStringToUTF8(error.reason));
return;
}
[[g_updater rac_valuesForKeyPath:@"state" observer:g_updater]
subscribeNext:^(NSNumber *stateNumber) {
int state = [stateNumber integerValue];
// Dispatching the event on main thread.
dispatch_async(dispatch_get_main_queue(), ^{
if (state == SQRLUpdaterStateCheckingForUpdate)
delegate->OnCheckingForUpdate();
else if (state == SQRLUpdaterStateDownloadingUpdate)
delegate->OnUpdateAvailable();
});
}];
for (const auto& it : requestHeaders) {
[urlRequest setValue:base::SysUTF8ToNSString(it.second)
forHTTPHeaderField:base::SysUTF8ToNSString(it.first)];
}
if (g_updater)
[g_updater release];
// Initialize the SQRLUpdater.
@try {
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
} @catch (NSException* error) {
delegate->OnError(base::SysNSStringToUTF8(error.reason));
return;
}
[[g_updater rac_valuesForKeyPath:@"state" observer:g_updater]
subscribeNext:^(NSNumber *stateNumber) {
int state = [stateNumber integerValue];
// Dispatching the event on main thread.
dispatch_async(dispatch_get_main_queue(), ^{
if (state == SQRLUpdaterStateCheckingForUpdate)
delegate->OnCheckingForUpdate();
else if (state == SQRLUpdaterStateDownloadingUpdate)
delegate->OnUpdateAvailable();
});
}];
}
// static

View file

@ -58,7 +58,7 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
if (!bundleList) {
return false;
}
// On Mac OS X, we can't query the default, but the handlers list seems to put
// On macOS, we can't query the default, but the handlers list seems to put
// Apple's defaults first, so we'll use the first option that isn't our bundle
CFStringRef other = nil;
for (CFIndex i = 0; i < CFArrayGetCount(bundleList); i++) {

View file

@ -33,7 +33,7 @@ class BrowserObserver {
virtual void OnQuit() {}
// The browser has opened a file by double clicking in Finder or dragging the
// file to the Dock icon. (OS X only)
// file to the Dock icon. (macOS only)
virtual void OnOpenFile(bool* prevent_default,
const std::string& file_path) {}
@ -53,7 +53,7 @@ class BrowserObserver {
const base::DictionaryValue& request_details) {}
#if defined(OS_MACOSX)
// The browser wants to resume a user activity via handoff. (OS X only)
// The browser wants to resume a user activity via handoff. (macOS only)
virtual void OnContinueUserActivity(
bool* prevent_default,
const std::string& type,

View file

@ -6,9 +6,14 @@
#import <Cocoa/Cocoa.h>
#include "brightray/browser/mac/event_dispatching_window.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "ui/events/keycodes/keyboard_codes.h"
@interface NSWindow (EventDispatchingWindow)
- (void)redispatchKeyEvent:(NSEvent*)event;
@end
namespace atom {
void CommonWebContentsDelegate::HandleKeyboardEvent(
@ -22,18 +27,8 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source);
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
if (!handled && event.os_event.window) {
// Handle the cmd+~ shortcut.
if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ &&
(event.os_event.keyCode == 50 /* ~ */)) {
if (event.os_event.modifierFlags & NSShiftKeyMask) {
[NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil];
} else {
[NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil];
}
}
}
if (event.os_event.window)
[event.os_event.window redispatchKeyEvent:event.os_event];
}
} // namespace atom

View file

@ -46,7 +46,8 @@ namespace atom {
NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options)
const mate::Dictionary& options,
NativeWindow* parent)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
transparent_(false),
@ -56,12 +57,17 @@ NativeWindow::NativeWindow(
sheet_offset_x_(0.0),
sheet_offset_y_(0.0),
aspect_ratio_(0.0),
parent_(parent),
is_modal_(false),
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_);
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
if (parent)
options.Get("modal", &is_modal_);
// Tell the content module to initialize renderer widget with transparent
// mode.
ui::GpuSwitchingManager::SetTransparent(transparent_);
@ -153,7 +159,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
SetFullScreen(true);
}
bool skip;
if (options.Get(options::kSkipTaskbar, &skip) && skip) {
if (options.Get(options::kSkipTaskbar, &skip)) {
SetSkipTaskbar(skip);
}
bool kiosk;
@ -282,6 +288,9 @@ bool NativeWindow::IsDocumentEdited() {
return false;
}
void NativeWindow::SetFocusable(bool focusable) {
}
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
@ -289,6 +298,10 @@ bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
void NativeWindow::SetParentWindow(NativeWindow* parent) {
parent_ = parent;
}
void NativeWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}
@ -394,6 +407,9 @@ void NativeWindow::CloseContents(content::WebContents* source) {
inspectable_web_contents_ = nullptr;
Observe(nullptr);
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
WillDestoryNativeObject());
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
@ -557,6 +573,22 @@ void NativeWindow::BeforeUnloadDialogCancelled() {
window_unresposive_closure_.Cancel();
}
void NativeWindow::DidFirstVisuallyNonEmptyPaint() {
if (IsVisible())
return;
// When there is a non-empty first paint, resize the RenderWidget to force
// Chromium to draw.
const auto view = web_contents()->GetRenderWidgetHostView();
view->Show();
view->SetSize(GetContentSize());
// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&NativeWindow::NotifyReadyToShow, GetWeakPtr()));
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
@ -592,12 +624,16 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
void NativeWindow::NotifyWindowUnresponsive() {
window_unresposive_closure_.Cancel();
if (!is_closed_ && !HasModalDialog())
if (!is_closed_ && !HasModalDialog() && IsEnabled())
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnRendererUnresponsive());
}
void NativeWindow::NotifyReadyToShow() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnReadyToShow());
}
void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {

View file

@ -81,7 +81,8 @@ class NativeWindow : public base::SupportsUserData,
// managing the window's live.
static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
const mate::Dictionary& options,
NativeWindow* parent = nullptr);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
@ -97,6 +98,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void ShowInactive() = 0;
virtual void Hide() = 0;
virtual bool IsVisible() = 0;
virtual bool IsEnabled() = 0;
virtual void Maximize() = 0;
virtual void Unmaximize() = 0;
virtual bool IsMaximized() = 0;
@ -155,8 +157,10 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetDocumentEdited(bool edited);
virtual bool IsDocumentEdited();
virtual void SetIgnoreMouseEvents(bool ignore) = 0;
virtual void SetFocusable(bool focusable);
virtual void SetMenu(ui::MenuModel* menu);
virtual bool HasModalDialog();
virtual void SetParentWindow(NativeWindow* parent);
virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
@ -254,9 +258,13 @@ class NativeWindow : public base::SupportsUserData,
has_dialog_attached_ = has_dialog_attached;
}
NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; }
protected:
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
const mate::Dictionary& options,
NativeWindow* parent);
// Convert draggable regions in raw format to SkRegion format. Caller is
// responsible for deleting the returned SkRegion instance.
@ -274,6 +282,7 @@ class NativeWindow : public base::SupportsUserData,
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
void DidFirstVisuallyNonEmptyPaint() override;
bool OnMessageReceived(const IPC::Message& message) override;
private:
@ -283,6 +292,9 @@ class NativeWindow : public base::SupportsUserData,
// Dispatch unresponsive event to observers.
void NotifyWindowUnresponsive();
// Dispatch ReadyToShow event to observers.
void NotifyReadyToShow();
// Called when CapturePage has done.
void OnCapturePageDone(const CapturePageCallback& callback,
const SkBitmap& bitmap,
@ -315,7 +327,7 @@ class NativeWindow : public base::SupportsUserData,
base::CancelableClosure window_unresposive_closure_;
// Used to display sheets at the appropriate horizontal and vertical offsets
// on OS X.
// on macOS.
double sheet_offset_x_;
double sheet_offset_y_;
@ -324,6 +336,12 @@ class NativeWindow : public base::SupportsUserData,
double aspect_ratio_;
gfx::Size aspect_ratio_extraSize_;
// The parent window, it is guaranteed to be valid during this window's life.
NativeWindow* parent_;
// Is this a modal window.
bool is_modal_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;

View file

@ -22,7 +22,8 @@ namespace atom {
class NativeWindowMac : public NativeWindow {
public:
NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
const mate::Dictionary& options,
NativeWindow* parent);
~NativeWindowMac() override;
// NativeWindow:
@ -34,6 +35,7 @@ class NativeWindowMac : public NativeWindow {
void ShowInactive() override;
void Hide() override;
bool IsVisible() override;
bool IsEnabled() override;
void Maximize() override;
void Unmaximize() override;
bool IsMaximized() override;
@ -78,6 +80,7 @@ class NativeWindowMac : public NativeWindow {
bool IsDocumentEdited() override;
void SetIgnoreMouseEvents(bool ignore) override;
bool HasModalDialog() override;
void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override;
gfx::AcceleratedWidget GetAcceleratedWidget() override;
void SetProgressBar(double progress) override;
@ -96,9 +99,12 @@ class NativeWindowMac : public NativeWindow {
void SetStyleMask(bool on, NSUInteger flag);
void SetCollectionBehavior(bool on, NSUInteger flag);
bool should_hide_native_toolbar_in_fullscreen() const {
return should_hide_native_toolbar_in_fullscreen_;
}
enum TitleBarStyle {
NORMAL,
HIDDEN,
HIDDEN_INSET,
};
TitleBarStyle title_bar_style() const { return title_bar_style_; }
protected:
// Return a vector of non-draggable regions that fill a window of size
@ -138,14 +144,8 @@ class NativeWindowMac : public NativeWindow {
// The presentation options before entering kiosk mode.
NSApplicationPresentationOptions kiosk_options_;
// The window title, for frameless windows we only set title when fullscreen.
std::string title_;
// Force showing the buttons for frameless window.
bool force_show_buttons_;
// Whether to hide the native toolbar under fullscreen mode.
bool should_hide_native_toolbar_in_fullscreen_;
// The "titleBarStyle" option.
TitleBarStyle title_bar_style_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
};

View file

@ -15,6 +15,7 @@
#include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "brightray/browser/mac/event_dispatching_window.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_view_host.h"
@ -184,7 +185,7 @@ bool ScopedDisableResize::disable_resize_ = false;
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
// Hide the native toolbar before entering fullscreen, so there is no visual
// artifacts.
if (shell_->should_hide_native_toolbar_in_fullscreen()) {
if (shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) {
NSWindow* window = shell_->GetNativeWindow();
[window setToolbar:nil];
}
@ -193,16 +194,20 @@ bool ScopedDisableResize::disable_resize_ = false;
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
shell_->NotifyWindowEnterFullScreen();
// For frameless window we don't set title for normal mode since the title
// bar is expected to be empty, but after entering fullscreen mode we have
// to set one, because title bar is visible here.
// For frameless window we don't show set title for normal mode since the
// titlebar is expected to be empty, but after entering fullscreen mode we
// have to set one, because title bar is visible here.
NSWindow* window = shell_->GetNativeWindow();
if (shell_->transparent() || !shell_->has_frame())
[window setTitle:base::SysUTF8ToNSString(shell_->GetTitle())];
if ((shell_->transparent() || !shell_->has_frame()) &&
// FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under
// fullscreen mode.
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
[window setTitleVisibility:NSWindowTitleVisible];
}
// Restore the native toolbar immediately after entering fullscreen, if we do
// this before leaving fullscreen, traffic light buttons will be jumping.
if (shell_->should_hide_native_toolbar_in_fullscreen()) {
if (shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) {
base::scoped_nsobject<NSToolbar> toolbar(
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
[toolbar setShowsBaselineSeparator:NO];
@ -215,18 +220,20 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (void)windowWillExitFullScreen:(NSNotification*)notification {
// Restore the title bar to empty.
// Restore the titlebar visibility.
NSWindow* window = shell_->GetNativeWindow();
if (shell_->transparent() || !shell_->has_frame())
[window setTitle:@""];
if ((shell_->transparent() || !shell_->has_frame()) &&
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
[window setTitleVisibility:NSWindowTitleHidden];
}
// Turn off the style for toolbar.
if (shell_->should_hide_native_toolbar_in_fullscreen())
if (shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET)
shell_->SetStyleMask(false, NSFullSizeContentViewWindowMask);
}
- (void)windowDidExitFullScreen:(NSNotification*)notification {
// For certain versions of OS X the fullscreen button will automatically show
// For certain versions of macOS the fullscreen button will automatically show
// after exiting fullscreen mode.
if (!shell_->has_frame()) {
NSWindow* window = shell_->GetNativeWindow();
@ -264,7 +271,7 @@ bool ScopedDisableResize::disable_resize_ = false;
@end
@interface AtomNSWindow : NSWindow {
@interface AtomNSWindow : EventDispatchingWindow {
@private
atom::NativeWindowMac* shell_;
bool enable_larger_than_screen_;
@ -395,16 +402,39 @@ bool ScopedDisableResize::disable_resize_ = false;
@end
namespace mate {
template<>
struct Converter<atom::NativeWindowMac::TitleBarStyle> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
atom::NativeWindowMac::TitleBarStyle* out) {
std::string title_bar_style;
if (!ConvertFromV8(isolate, val, &title_bar_style))
return false;
if (title_bar_style == "hidden") {
*out = atom::NativeWindowMac::HIDDEN;
} else if (title_bar_style == "hidden-inset" || // Deprecate this after 2.0
title_bar_style == "hiddenInset") {
*out = atom::NativeWindowMac::HIDDEN_INSET;
} else {
return false;
}
return true;
}
};
} // namespace mate
namespace atom {
NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options, parent),
is_kiosk_(false),
attention_request_id_(0),
force_show_buttons_(false),
should_hide_native_toolbar_in_fullscreen_(false) {
title_bar_style_(NORMAL) {
int width = 800, height = 600;
options.Get(options::kWidth, &width);
options.Get(options::kHeight, &height);
@ -429,9 +459,8 @@ NativeWindowMac::NativeWindowMac(
options.Get(options::kClosable, &closable);
// New title bar styles are available in Yosemite or newer
std::string titleBarStyle;
if (base::mac::IsOSYosemiteOrLater())
options.Get(options::kTitleBarStyle, &titleBarStyle);
options.Get(options::kTitleBarStyle, &title_bar_style_);
std::string windowType;
options.Get(options::kType, &windowType);
@ -451,10 +480,9 @@ NativeWindowMac::NativeWindowMac(
if (closable) {
styleMask |= NSClosableWindowMask;
}
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
if (title_bar_style_ != NORMAL) {
// The window without titlebar is treated the same with frameless window.
set_has_frame(false);
force_show_buttons_ = true;
}
if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask;
@ -474,9 +502,12 @@ NativeWindowMac::NativeWindowMac(
window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]);
[window_ setDelegate:window_delegate_];
// Only use native parent window for non-modal windows.
if (parent && !is_modal()) {
SetParentWindow(parent);
}
if (transparent()) {
// Make window has transparent background.
[window_ setOpaque:NO];
// Setting the background color to clear will also hide the shadow.
[window_ setBackgroundColor:[NSColor clearColor]];
}
@ -490,25 +521,30 @@ NativeWindowMac::NativeWindowMac(
NSWindowCollectionBehaviorIgnoresCycle)];
}
// Remove non-transparent corners, see http://git.io/vfonD.
if (!has_frame())
bool focusable;
if (options.Get(options::kFocusable, &focusable) && !focusable)
[window_ setDisableKeyOrMainWindow:YES];
if (transparent() || !has_frame()) {
// Don't show title bar.
[window_ setTitleVisibility:NSWindowTitleHidden];
// Remove non-transparent corners, see http://git.io/vfonD.
[window_ setOpaque:NO];
}
// We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO];
// Hide the title bar.
if (titleBarStyle == "hidden-inset") {
if (title_bar_style_ == HIDDEN_INSET) {
[window_ setTitlebarAppearsTransparent:YES];
[window_ setTitleVisibility:NSWindowTitleHidden];
base::scoped_nsobject<NSToolbar> toolbar(
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
[toolbar setShowsBaselineSeparator:NO];
[window_ setToolbar:toolbar];
should_hide_native_toolbar_in_fullscreen_ = true;
}
// On OS X the initial window size doesn't include window frame.
// On macOS the initial window size doesn't include window frame.
bool use_content_size = false;
options.Get(options::kUseContentSize, &use_content_size);
if (!has_frame() || !use_content_size)
@ -565,6 +601,12 @@ NativeWindowMac::~NativeWindowMac() {
}
void NativeWindowMac::Close() {
// When this is a sheet showing, performClose won't work.
if (is_modal() && parent() && IsVisible()) {
CloseImmediately();
return;
}
if (!IsClosable()) {
WindowList::WindowCloseCancelled(this);
return;
@ -594,6 +636,12 @@ bool NativeWindowMac::IsFocused() {
}
void NativeWindowMac::Show() {
if (is_modal() && parent()) {
[parent()->GetNativeWindow() beginSheet:window_
completionHandler:^(NSModalResponse) {}];
return;
}
// This method is supposed to put focus on window, however if the app does not
// have focus then "makeKeyAndOrderFront" will only show the window.
[NSApp activateIgnoringOtherApps:YES];
@ -606,6 +654,12 @@ void NativeWindowMac::ShowInactive() {
}
void NativeWindowMac::Hide() {
if (is_modal() && parent()) {
[window_ orderOut:nil];
[parent()->GetNativeWindow() endSheet:window_];
return;
}
[window_ orderOut:nil];
}
@ -613,6 +667,10 @@ bool NativeWindowMac::IsVisible() {
return [window_ isVisible];
}
bool NativeWindowMac::IsEnabled() {
return [window_ attachedSheet] == nil;
}
void NativeWindowMac::Maximize() {
if (IsMaximized())
return;
@ -794,17 +852,11 @@ void NativeWindowMac::Center() {
}
void NativeWindowMac::SetTitle(const std::string& title) {
title_ = title;
// We don't want the title to show in transparent or frameless window.
if (transparent() || !has_frame())
return;
[window_ setTitle:base::SysUTF8ToNSString(title)];
}
std::string NativeWindowMac::GetTitle() {
return title_;
return base::SysNSStringToUTF8([window_ title]);;
}
void NativeWindowMac::FlashFrame(bool flash) {
@ -887,6 +939,21 @@ bool NativeWindowMac::HasModalDialog() {
return [window_ attachedSheet] != nil;
}
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
if (is_modal())
return;
NativeWindow::SetParentWindow(parent);
// Remove current parent window.
if ([window_ parentWindow])
[[window_ parentWindow] removeChildWindow:window_];
// Set new current window.
if (parent)
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
}
gfx::NativeWindow NativeWindowMac::GetNativeWindow() {
return window_;
}
@ -903,7 +970,9 @@ void NativeWindowMac::SetProgressBar(double progress) {
NSImageView* image_view = [[NSImageView alloc] init];
[image_view setImage:[NSApp applicationIconImage]];
[dock_tile setContentView:image_view];
}
if ([[dock_tile.contentView subviews] count] == 0) {
NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc]
initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)];
[progress_indicator setStyle:NSProgressIndicatorBarStyle];
@ -912,7 +981,7 @@ void NativeWindowMac::SetProgressBar(double progress) {
[progress_indicator setMinValue:0];
[progress_indicator setMaxValue:1];
[progress_indicator setHidden:NO];
[image_view addSubview:progress_indicator];
[dock_tile.contentView addSubview:progress_indicator];
}
NSProgressIndicator* progress_indicator =
@ -1008,7 +1077,7 @@ void NativeWindowMac::InstallView() {
[view setFrame:[content_view_ bounds]];
[content_view_ addSubview:view];
if (force_show_buttons_)
if (title_bar_style_ != NORMAL)
return;
// Hide the window buttons.
@ -1016,7 +1085,7 @@ void NativeWindowMac::InstallView() {
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
// Some third-party OS X utilities check the zoom button's enabled state to
// Some third-party macOS utilities check the zoom button's enabled state to
// determine whether to show custom UI on hover, so we disable it here to
// prevent them from doing so in a frameless app window.
[[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO];
@ -1086,7 +1155,7 @@ void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
else
[window_ setStyleMask:[window_ styleMask] & (~flag)];
// Change style mask will make the zoom button revert to default, probably
// a bug of Cocoa or OS X.
// a bug of Cocoa or macOS.
if (!zoom_button_enabled)
SetMaximizable(false);
}
@ -1098,7 +1167,7 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
else
[window_ setCollectionBehavior:[window_ collectionBehavior] & (~flag)];
// Change collectionBehavior will make the zoom button revert to default,
// probably a bug of Cocoa or OS X.
// probably a bug of Cocoa or macOS.
if (!zoom_button_enabled)
SetMaximizable(false);
}
@ -1106,8 +1175,9 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
// static
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(inspectable_web_contents, options);
const mate::Dictionary& options,
NativeWindow* parent) {
return new NativeWindowMac(inspectable_web_contents, options, parent);
}
} // namespace atom

View file

@ -33,6 +33,9 @@ class NativeWindowObserver {
// Called when the window is gonna closed.
virtual void WillCloseWindow(bool* prevent_default) {}
// Called before the native window object is going to be destroyed.
virtual void WillDestoryNativeObject() {}
// Called when the window is closed.
virtual void OnWindowClosed() {}
@ -48,6 +51,9 @@ class NativeWindowObserver {
// Called when window is hidden.
virtual void OnWindowHide() {}
// Called when window is ready to show.
virtual void OnReadyToShow() {}
// Called when window state changed.
virtual void OnWindowMaximize() {}
virtual void OnWindowUnmaximize() {}

View file

@ -29,6 +29,7 @@
#include "ui/views/window/client_view.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/core/shadow_types.h"
#if defined(USE_X11)
@ -36,6 +37,7 @@
#include "atom/browser/ui/views/global_menu_bar_x11.h"
#include "atom/browser/ui/views/frameless_view.h"
#include "atom/browser/ui/views/native_frame_view.h"
#include "atom/browser/ui/x/event_disabler.h"
#include "atom/browser/ui/x/window_state_watcher.h"
#include "atom/browser/ui/x/x_window_utils.h"
#include "base/strings/string_util.h"
@ -125,14 +127,16 @@ class NativeWindowClientView : public views::ClientView {
NativeWindowViews::NativeWindowViews(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options, parent),
window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()),
menu_bar_autohide_(false),
menu_bar_visible_(false),
menu_bar_alt_pressed_(false),
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
disable_count_(0),
use_content_size_(false),
movable_(true),
resizable_(true),
@ -181,7 +185,14 @@ NativeWindowViews::NativeWindowViews(
if (transparent() && !has_frame())
params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
bool focusable;
if (options.Get(options::kFocusable, &focusable) && !focusable)
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
#if defined(OS_WIN)
if (parent)
params.parent = parent->GetNativeWindow();
params.native_widget =
new views::DesktopNativeWidgetAura(window_.get());
atom_desktop_window_tree_host_win_ = new AtomDesktopWindowTreeHostWin(
@ -232,12 +243,23 @@ NativeWindowViews::NativeWindowViews(
state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
}
std::string window_type;
options.Get(options::kType, &window_type);
if (parent) {
SetParentWindow(parent);
// Force using dialog type for child window.
window_type = "dialog";
// Modal window needs the _NET_WM_STATE_MODAL hint.
if (is_modal())
state_atom_list.push_back(GetAtom("_NET_WM_STATE_MODAL"));
}
ui::SetAtomArrayProperty(GetAcceleratedWidget(), "_NET_WM_STATE", "ATOM",
state_atom_list);
// Set the _NET_WM_WINDOW_TYPE.
std::string window_type;
if (options.Get(options::kType, &window_type))
if (!window_type.empty())
SetWindowType(GetAcceleratedWidget(), window_type);
#endif
@ -333,6 +355,9 @@ bool NativeWindowViews::IsFocused() {
}
void NativeWindowViews::Show() {
if (is_modal() && NativeWindow::parent())
static_cast<NativeWindowViews*>(NativeWindow::parent())->SetEnabled(false);
window_->native_widget_private()->ShowWithWindowState(GetRestoredState());
NotifyWindowShow();
@ -355,6 +380,9 @@ void NativeWindowViews::ShowInactive() {
}
void NativeWindowViews::Hide() {
if (is_modal() && NativeWindow::parent())
static_cast<NativeWindowViews*>(NativeWindow::parent())->SetEnabled(true);
window_->Hide();
NotifyWindowHide();
@ -369,6 +397,14 @@ bool NativeWindowViews::IsVisible() {
return window_->IsVisible();
}
bool NativeWindowViews::IsEnabled() {
#if defined(OS_WIN)
return ::IsWindowEnabled(GetAcceleratedWidget());
#elif defined(USE_X11)
return !event_disabler_.get();
#endif
}
void NativeWindowViews::Maximize() {
if (IsVisible())
window_->Maximize();
@ -692,6 +728,19 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) {
#endif
}
void NativeWindowViews::SetFocusable(bool focusable) {
#if defined(OS_WIN)
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
if (focusable)
ex_style &= ~WS_EX_NOACTIVATE;
else
ex_style |= WS_EX_NOACTIVATE;
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
SetSkipTaskbar(!focusable);
Focus(false);
#endif
}
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (menu_model == nullptr) {
// Remove accelerators
@ -755,6 +804,32 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
Layout();
}
void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
NativeWindow::SetParentWindow(parent);
#if defined(USE_X11)
XDisplay* xdisplay = gfx::GetXDisplay();
XSetTransientForHint(
xdisplay, GetAcceleratedWidget(),
parent? parent->GetAcceleratedWidget() : DefaultRootWindow(xdisplay));
#elif defined(OS_WIN) && defined(DEBUG)
// Should work, but does not, it seems that the views toolkit doesn't support
// reparenting on desktop.
if (parent) {
::SetParent(GetAcceleratedWidget(), parent->GetAcceleratedWidget());
views::Widget::ReparentNativeView(GetNativeWindow(),
parent->GetNativeWindow());
wm::AddTransientChild(parent->GetNativeWindow(), GetNativeWindow());
} else {
if (!GetNativeWindow()->parent())
return;
::SetParent(GetAcceleratedWidget(), NULL);
views::Widget::ReparentNativeView(GetNativeWindow(), nullptr);
wm::RemoveTransientChild(GetNativeWindow()->parent(), GetNativeWindow());
}
#endif
}
gfx::NativeWindow NativeWindowViews::GetNativeWindow() {
return window_->GetNativeWindow();
}
@ -850,6 +925,33 @@ void NativeWindowViews::SetIcon(const gfx::ImageSkia& icon) {
}
#endif
void NativeWindowViews::SetEnabled(bool enable) {
// Handle multiple calls of SetEnabled correctly.
if (enable) {
--disable_count_;
if (disable_count_ != 0)
return;
} else {
++disable_count_;
if (disable_count_ != 1)
return;
}
#if defined(OS_WIN)
::EnableWindow(GetAcceleratedWidget(), enable);
#elif defined(USE_X11)
views::DesktopWindowTreeHostX11* tree_host =
views::DesktopWindowTreeHostX11::GetHostForXID(GetAcceleratedWidget());
if (enable) {
tree_host->RemoveEventRewriter(event_disabler_.get());
event_disabler_.reset();
} else {
event_disabler_.reset(new EventDisabler);
tree_host->AddEventRewriter(event_disabler_.get());
}
#endif
}
void NativeWindowViews::OnWidgetActivationChanged(
views::Widget* widget, bool active) {
if (widget != window_.get())
@ -883,6 +985,15 @@ void NativeWindowViews::OnWidgetBoundsChanged(
}
void NativeWindowViews::DeleteDelegate() {
if (is_modal() && NativeWindow::parent()) {
NativeWindowViews* parent =
static_cast<NativeWindowViews*>(NativeWindow::parent());
// Enable parent window after current window gets closed.
parent->SetEnabled(true);
// Focus on parent window.
parent->Focus(true);
}
NotifyWindowClosed();
}
@ -1093,8 +1204,9 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() {
// static
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(inspectable_web_contents, options);
const mate::Dictionary& options,
NativeWindow* parent) {
return new NativeWindowViews(inspectable_web_contents, options, parent);
}
} // namespace atom

View file

@ -32,6 +32,8 @@ class WindowStateWatcher;
#if defined(OS_WIN)
class AtomDesktopWindowTreeHostWin;
#elif defined(USE_X11)
class EventDisabler;
#endif
class NativeWindowViews : public NativeWindow,
@ -42,7 +44,8 @@ class NativeWindowViews : public NativeWindow,
public views::WidgetObserver {
public:
NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
const mate::Dictionary& options,
NativeWindow* parent);
~NativeWindowViews() override;
// NativeWindow:
@ -54,6 +57,7 @@ class NativeWindowViews : public NativeWindow,
void ShowInactive() override;
void Hide() override;
bool IsVisible() override;
bool IsEnabled() override;
void Maximize() override;
void Unmaximize() override;
bool IsMaximized() override;
@ -92,7 +96,9 @@ class NativeWindowViews : public NativeWindow,
void SetHasShadow(bool has_shadow) override;
bool HasShadow() override;
void SetIgnoreMouseEvents(bool ignore) override;
void SetFocusable(bool focusable) override;
void SetMenu(ui::MenuModel* menu_model) override;
void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) override;
@ -112,6 +118,8 @@ class NativeWindowViews : public NativeWindow,
void SetIcon(const gfx::ImageSkia& icon);
#endif
void SetEnabled(bool enable);
views::Widget* widget() const { return window_.get(); }
#if defined(OS_WIN)
@ -186,6 +194,9 @@ class NativeWindowViews : public NativeWindow,
// Handles window state events.
std::unique_ptr<WindowStateWatcher> window_state_watcher_;
// To disable the mouse events.
std::unique_ptr<EventDisabler> event_disabler_;
// The "resizable" flag on Linux is implemented by setting size constraints,
// we need to make sure size constraints are restored when window becomes
// resizable again.
@ -219,6 +230,9 @@ class NativeWindowViews : public NativeWindow,
// Map from accelerator to menu item's command id.
accelerator_util::AcceleratorTable accelerator_table_;
// How many times the Disable has been called.
int disable_count_;
bool use_content_size_;
bool movable_;
bool resizable_;

View file

@ -5,6 +5,7 @@
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
@ -41,14 +42,24 @@ bool AtomURLRequestJobFactory::SetProtocolHandler(
return true;
}
std::unique_ptr<ProtocolHandler> AtomURLRequestJobFactory::ReplaceProtocol(
bool AtomURLRequestJobFactory::InterceptProtocol(
const std::string& scheme,
std::unique_ptr<ProtocolHandler> protocol_handler) {
if (!ContainsKey(protocol_handler_map_, scheme))
return nullptr;
if (!ContainsKey(protocol_handler_map_, scheme) ||
ContainsKey(original_protocols_, scheme))
return false;
ProtocolHandler* original_protocol_handler = protocol_handler_map_[scheme];
protocol_handler_map_[scheme] = protocol_handler.release();
return make_scoped_ptr(original_protocol_handler);
original_protocols_.set(scheme, base::WrapUnique(original_protocol_handler));
return true;
}
bool AtomURLRequestJobFactory::UninterceptProtocol(const std::string& scheme) {
if (!original_protocols_.contains(scheme))
return false;
protocol_handler_map_[scheme] =
original_protocols_.take_and_erase(scheme).release();
return true;
}
ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(

View file

@ -7,11 +7,11 @@
#define ATOM_BROWSER_NET_ATOM_URL_REQUEST_JOB_FACTORY_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "net/url_request/url_request_job_factory.h"
namespace atom {
@ -27,11 +27,11 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
bool SetProtocolHandler(const std::string& scheme,
std::unique_ptr<ProtocolHandler> protocol_handler);
// Intercepts the ProtocolHandler for a scheme. Returns the original protocol
// handler on success, otherwise returns NULL.
std::unique_ptr<ProtocolHandler> ReplaceProtocol(
// Intercepts the ProtocolHandler for a scheme.
bool InterceptProtocol(
const std::string& scheme,
std::unique_ptr<ProtocolHandler> protocol_handler);
bool UninterceptProtocol(const std::string& scheme);
// Returns the protocol handler registered with scheme.
ProtocolHandler* GetProtocolHandler(const std::string& scheme) const;
@ -60,6 +60,12 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
ProtocolHandlerMap protocol_handler_map_;
// Map that stores the original protocols of schemes.
using OriginalProtocolsMap = base::ScopedPtrHashMap<
std::string, std::unique_ptr<ProtocolHandler>>;
// Can only be accessed in IO thread.
OriginalProtocolsMap original_protocols_;
DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory);
};

View file

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

View file

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

View file

@ -79,7 +79,7 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
for (size_t i = 0; i < buttons.size(); ++i) {
NSString* title = base::SysUTF8ToNSString(buttons[i]);
// An empty title causes crash on OS X.
// An empty title causes crash on macOS.
if (buttons[i].empty())
title = @"(empty)";
NSButton* button = [alert addButtonWithTitle:title];

View file

@ -40,11 +40,11 @@ class TrayIcon {
virtual void SetToolTip(const std::string& tool_tip) = 0;
// Sets the title displayed aside of the status icon in the status bar. This
// only works on OS X.
// only works on macOS.
virtual void SetTitle(const std::string& title);
// Sets whether the status icon is highlighted when it is clicked. This only
// works on OS X.
// works on macOS.
virtual void SetHighlightMode(bool highlight);
// Displays a notification balloon with the specified contents.

View file

@ -12,9 +12,9 @@
namespace {
// By default, OS X sets 4px to tray image as left and right padding margin.
// By default, macOS sets 4px to tray image as left and right padding margin.
const CGFloat kHorizontalMargin = 4;
// OS X tends to make the title 2px lower.
// macOS tends to make the title 2px lower.
const CGFloat kVerticalTitleMargin = 2;
} // namespace

View file

@ -4,7 +4,8 @@
#include "atom/browser/ui/tray_icon_gtk.h"
#include "base/guid.h"
#include "atom/browser/browser.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h"
@ -12,6 +13,13 @@
namespace atom {
namespace {
// Number of app indicators used (used as part of app-indicator id).
int indicators_count;
} // namespace
TrayIconGtk::TrayIconGtk() {
}
@ -25,11 +33,16 @@ void TrayIconGtk::SetImage(const gfx::Image& image) {
}
base::string16 empty;
if (libgtk2ui::AppIndicatorIcon::CouldOpen())
if (libgtk2ui::AppIndicatorIcon::CouldOpen()) {
++indicators_count;
icon_.reset(new libgtk2ui::AppIndicatorIcon(
base::GenerateGUID(), image.AsImageSkia(), empty));
else
base::StringPrintf(
"%s%d", Browser::Get()->GetName().c_str(), indicators_count),
image.AsImageSkia(),
empty));
} else {
icon_.reset(new libgtk2ui::Gtk2StatusIcon(image.AsImageSkia(), empty));
}
icon_->set_delegate(this);
}

View file

@ -0,0 +1,27 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/ui/x/event_disabler.h"
namespace atom {
EventDisabler::EventDisabler() {
}
EventDisabler::~EventDisabler() {
}
ui::EventRewriteStatus EventDisabler::RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) {
return ui::EVENT_REWRITE_DISCARD;
}
ui::EventRewriteStatus EventDisabler::NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) {
return ui::EVENT_REWRITE_CONTINUE;
}
} // namespace atom

View file

@ -0,0 +1,32 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_X_EVENT_DISABLER_H_
#define ATOM_BROWSER_UI_X_EVENT_DISABLER_H_
#include "base/macros.h"
#include "ui/events/event_rewriter.h"
namespace atom {
class EventDisabler : public ui::EventRewriter {
public:
EventDisabler();
~EventDisabler() override;
// ui::EventRewriter:
ui::EventRewriteStatus RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) override;
ui::EventRewriteStatus NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) override;
private:
DISALLOW_COPY_AND_ASSIGN(EventDisabler);
};
} // namespace atom
#endif // ATOM_BROWSER_UI_X_EVENT_DISABLER_H_

View file

@ -15,24 +15,6 @@ using crash_reporter::CrashReporter;
namespace mate {
template<>
struct Converter<std::map<std::string, std::string> > {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
std::map<std::string, std::string>* out) {
if (!val->IsObject())
return false;
v8::Local<v8::Object> dict = val->ToObject();
v8::Local<v8::Array> keys = dict->GetOwnPropertyNames();
for (uint32_t i = 0; i < keys->Length(); ++i) {
v8::Local<v8::Value> key = keys->Get(i);
(*out)[V8ToString(key)] = V8ToString(dict->Get(key));
}
return true;
}
};
template<>
struct Converter<CrashReporter::UploadReportResult> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,

View file

@ -64,7 +64,7 @@ v8::Local<v8::Value> GetSystemMemoryInfo(v8::Isolate* isolate,
dict.Set("total", mem_info.total);
dict.Set("free", mem_info.free);
// NB: These return bogus values on OS X
// NB: These return bogus values on macOS
#if !defined(OS_MACOSX)
dict.Set("swapTotal", mem_info.swap_total);
dict.Set("swapFree", mem_info.swap_free);

View file

@ -7,7 +7,7 @@
#define ATOM_MAJOR_VERSION 1
#define ATOM_MINOR_VERSION 2
#define ATOM_PATCH_VERSION 2
#define ATOM_PATCH_VERSION 3
#define ATOM_VERSION_IS_RELEASE 1

View file

@ -8,7 +8,7 @@
#ifndef ATOM_COMMON_CHROME_VERSION_H_
#define ATOM_COMMON_CHROME_VERSION_H_
#define CHROME_VERSION_STRING "51.0.2704.84"
#define CHROME_VERSION_STRING "51.0.2704.103"
#define CHROME_VERSION "v" CHROME_VERSION_STRING
#endif // ATOM_COMMON_CHROME_VERSION_H_

View file

@ -14,10 +14,6 @@
namespace atom {
namespace internal {
} // namespace internal
// Like ES6's WeakMap, but the key is Integer and the value is Weak Pointer.
template<typename K>
class KeyWeakMap {
@ -57,7 +53,7 @@ class KeyWeakMap {
}
// Returns all objects.
std::vector<v8::Local<v8::Object>> Values(v8::Isolate* isolate) {
std::vector<v8::Local<v8::Object>> Values(v8::Isolate* isolate) const {
std::vector<v8::Local<v8::Object>> keys;
keys.reserve(map_.size());
for (const auto& iter : map_) {

View file

@ -22,7 +22,7 @@
#undef DISALLOW_COPY_AND_ASSIGN
#undef NO_RETURN
#undef arraysize
#undef debug_string // This is defined in OS X 10.9 SDK in AssertMacros.h.
#undef debug_string // This is defined in macOS 10.9 SDK in AssertMacros.h.
#include "vendor/node/src/env.h"
#include "vendor/node/src/env-inl.h"
#include "vendor/node/src/node.h"

View file

@ -66,7 +66,7 @@ const char kType[] = "type";
// Disable auto-hiding cursor.
const char kDisableAutoHideCursor[] = "disableAutoHideCursor";
// Use the OS X's standard window instead of the textured window.
// Use the macOS' standard window instead of the textured window.
const char kStandardWindow[] = "standardWindow";
// Default browser window background color.
@ -75,6 +75,9 @@ const char kBackgroundColor[] = "backgroundColor";
// Whether the window should have a shadow.
const char kHasShadow[] = "hasShadow";
// Whether the window can be activated.
const char kFocusable[] = "focusable";
// The WebPreferences.
const char kWebPreferences[] = "webPreferences";

View file

@ -44,6 +44,7 @@ extern const char kDisableAutoHideCursor[];
extern const char kStandardWindow[];
extern const char kBackgroundColor[];
extern const char kHasShadow[];
extern const char kFocusable[];
extern const char kWebPreferences[];
// WebPreferences.

View file

@ -8,6 +8,7 @@
#import <Cocoa/Cocoa.h>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_aedesc.h"
@ -17,7 +18,11 @@
namespace platform_util {
void ShowItemInFolder(const base::FilePath& full_path) {
void ShowItemInFolder(const base::FilePath& path) {
// The API only takes absolute path.
base::FilePath full_path =
path.IsAbsolute() ? path : base::MakeAbsoluteFilePath(path);
DCHECK([NSThread isMainThread]);
NSString* path_string = base::SysUTF8ToNSString(full_path.value());
if (!path_string || ![[NSWorkspace sharedWorkspace] selectFile:path_string

View file

@ -282,6 +282,11 @@ void AtomRendererClient::DidCreateScriptContext(
void AtomRendererClient::WillReleaseScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) {
// Only allow node integration for the main frame, unless it is a devtools
// extension page.
if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame))
return;
node::Environment* env = node::Environment::GetCurrent(context);
if (env)
mate::EmitEvent(env->isolate(), env->process_object(), "exit");

View file

@ -124,7 +124,7 @@
],
'conditions': [
['OS=="mac" and libchromiumcontent_component==0', {
# -all_load is the "whole-archive" on OS X.
# -all_load is the "whole-archive" on macOS.
'xcode_settings': {
'OTHER_LDFLAGS': [ '-Wl,-all_load' ],
},

View file

@ -3,7 +3,6 @@ const {app, dialog, shell, Menu} = require('electron')
const fs = require('fs')
const Module = require('module')
const path = require('path')
const repl = require('repl')
const url = require('url')
// Parse command line options.
@ -80,6 +79,15 @@ app.once('ready', () => {
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Paste and Match Style',
accelerator: 'Shift+Command+V',
role: 'pasteandmatchstyle'
},
{
label: 'Delete',
role: 'delete'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
@ -210,7 +218,21 @@ app.once('ready', () => {
}
]
})
template[3].submenu.push(
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
@ -218,7 +240,7 @@ app.once('ready', () => {
label: 'Bring All to Front',
role: 'front'
}
)
]
}
const menu = Menu.buildFromTemplate(template)
@ -286,6 +308,13 @@ function loadApplicationByUrl (appUrl) {
}
function startRepl () {
if (process.platform === 'win32') {
console.error('Electron REPL not currently supported on Windows')
process.exit(1)
return
}
const repl = require('repl')
repl.start('> ').on('exit', () => {
process.exit(0)
})

View file

@ -38,7 +38,7 @@ El objeto `process` tiene los siguientes métodos:
Interrumpe el hilo principal del proceso actual.
### process.setFdLimit(maxDescriptors) _OS X_ _Linux_
### process.setFdLimit(maxDescriptors) _macOS_ _Linux_
* `maxDescriptors` Integer

View file

@ -1,9 +1,9 @@
#Instrucciones de Compilación (Mac)
Siga las siguientes pautas para la construcción de Electron en OS X.
Siga las siguientes pautas para la construcción de Electron en macOS.
#Requisitos previos
`OS X >= 10.8`
`macOS >= 10.8`
`Xcode >= 5.1`
`node.js (external)`
@ -36,7 +36,7 @@ Después de la construcción está hecho, usted puede encontrar `Electron.app` b
#Soporte de 32bit
Electron sólo puede construirse para un objetivo de 64 bits en OS X y no hay un plan para apoyar a 32 bit OS X en el futuro.
Electron sólo puede construirse para un objetivo de 64 bits en macOS y no hay un plan para apoyar a 32 bit macOS en el futuro.
#Pruebas

View file

@ -26,7 +26,7 @@ Estas son las maneras en las que construimos la documentación de Electron.
- Argumentos opcionales son denotados cuando se llaman en listas.
- Delimitador de línea de 80-columnas.
- Métodos específicos de Plataformas son denotados en itálicas seguidas por la cabecera del método.
- ```### `method(foo, bar)` _OS X_```
- ```### `method(foo, bar)` _macOS_```
- Preferir 'en el ___ proceso' en lugar de 'sobre el'
### Traducciones de la Documentación

View file

@ -5,7 +5,7 @@ aplicación deberá llamarse `app`, y ser colocado debajo del directorio de
recursos de Electron (en OSX es `Electron.app/Contents/Resources/`, en Linux y
Windows es `resources/`), de esta forma:
En OS X:
En macOS:
```text
electron/Electron.app/Contents/Resources/app/
@ -37,7 +37,7 @@ Para utilizar un archivo `asar` en reemplazo del directorio `app`, debes de
renombrar el archivo a `app.asar`, y colocarlo por debajo el directorio de recursos
de Electron (ver en seguida), Electron intentará leer el archivo y arrancar desde el.
En OS X:
En macOS:
```text
electron/Electron.app/Contents/Resources/

View file

@ -6,9 +6,9 @@ en la JumpList de la barra de tareas, y en Mac, las aplicaciones pueden agregar
Esta guía explica cómo integrar tu aplicación en esos entornos de escritorio a través de las APIs de Electron.
## Documentos recientes (Windows y OS X)
## Documentos recientes (Windows y macOS)
Windows y OS X proveen un acceso sencillo a la lista de documentos recientes.
Windows y macOS proveen un acceso sencillo a la lista de documentos recientes.
__JumpList:__
@ -42,14 +42,14 @@ registrar tu aplicación en [Application Registration][app-registration].
Cuando un usuario haga click en un archivo de la JumpList, una nueva instancia de tu aplicación
se iniciará, la ruta del archivo se agregará como un argumento de la línea de comandos.
### Notas sobre OS X
### Notas sobre macOS
Cuando un archivo es solicitado desde el menú de documentos recientes, el evento `open-file`
del módulo `app` será emitido.
## Menú dock personalizado (OS X)
## Menú dock personalizado (macOS)
OS X permite a los desarrolladores definir un menú personalizado para el dock,
macOS permite a los desarrolladores definir un menú personalizado para el dock,
el cual usualmente contiene algunos accesos directos a las características más comunes
de tu aplicación:
@ -99,7 +99,7 @@ __Tareas de Internet Explorer:__
![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png)
A diferencia del menú dock en OS X, el cual es un menú real, las tareas de usuario en Windows
A diferencia del menú dock en macOS, el cual es un menú real, las tareas de usuario en Windows
funcionan como accesos directos de aplicación, que al ser clickeados, lanzan el programa
con argumentos específicos.

View file

@ -74,7 +74,7 @@ var mainWindow = null;
// Salir de todas las ventanas cuando se cierren.
app.on('window-all-closed', function() {
// En OS X es común que las aplicaciones y su barra de menú
// En macOS es común que las aplicaciones y su barra de menú
// se mantengan activas hasta que el usuario cierre la aplicación
// explícitamente utilizando Cmd + Q
if (process.platform != 'darwin') {
@ -139,7 +139,7 @@ En Linux:
$ ./electron/electron your-app/
```
En OS X:
En macOS:
```bash
$ ./Electron.app/Contents/MacOS/Electron your-app/

View file

@ -2,10 +2,10 @@
Las siguientes plataformas son soportadas por Electron:
### OS X
### macOS
Sólo se proveen binarios de 64 bit para OS X.
La versión mínima soportada es OS X 10.8.
Sólo se proveen binarios de 64 bit para macOS.
La versión mínima soportada es macOS 10.8.
### Windows

View file

@ -28,7 +28,7 @@ app.on('window-all-closed', function() {
// Specify flash path.
// On Windows, it might be /path/to/pepflashplayer.dll
// On OS X, /path/to/PepperFlashPlayer.plugin
// On macOS, /path/to/PepperFlashPlayer.plugin
// On Linux, /path/to/libpepflashplayer.so
app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so');

View file

@ -85,7 +85,7 @@ dans la FAQ :
* [Hiérarchie du Code Source](development/source-code-directory-structure.md)
* [Différences Techniques par rapport à NW.js (anciennement node-webkit)](development/atom-shell-vs-node-webkit.md)
* [Aperçu du Système de Build](development/build-system-overview.md)
* [Instructions de Build (OS X)](development/build-instructions-osx.md)
* [Instructions de Build (macOS)](development/build-instructions-osx.md)
* [Instructions de Build (Windows)](development/build-instructions-windows.md)
* [Instructions de Build (Linux)](development/build-instructions-linux.md)
* [Installer un Serveur de Symbol dans le debugger](development/setting-up-symbol-server.md)

View file

@ -27,7 +27,7 @@ La documentation d'Electron a été écrite en suivant les règles ci-dessous :
- Les arguments optionnels sont indiqués quand appelés dans la liste.
- La longueur des lignes ne dépasse pas 80 caractères.
- Les méthodes spécifiques à une plateforme sont notées en italique.
- ```### `method(foo, bar)` _OS X_```
- ```### `method(foo, bar)` _macOS_```
- Préférer 'in the ___ process' au lieu de 'on'
### Traductions de la Documentation

View file

@ -89,7 +89,7 @@ _リンクになっていないリストは未翻訳のものです。_
* 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 (macOS) (development/build-instructions-osx.md)
* Build Instructions (Windows) (development/build-instructions-windows.md)
* Build Instructions (Linux) (development/build-instructions-linux.md)
* Debug Instructions (Windows) (development/debug-instructions-windows.md)

View file

@ -10,9 +10,9 @@ acceleratorは、キーボードショートカットを示す文字列です。
## プラットフォームの留意点
OS Xでは`Command` キー、LinuxとWindowsでは`Control` キーを意味する`CommandOrControl`はいくつかのacceleratorを定義しますが、LinuxとWindowsでは、`Command` キーは何の効果もありません。
macOSでは`Command` キー、LinuxとWindowsでは`Control` キーを意味する`CommandOrControl`はいくつかのacceleratorを定義しますが、LinuxとWindowsでは、`Command` キーは何の効果もありません。
`Super` キーは、WindowsとLinuxでは `Windows` キーに、OS Xでは、`Cmd` キーに関連付けられます。
`Super` キーは、WindowsとLinuxでは `Windows` キーに、macOSでは、`Cmd` キーに関連付けられます。
## 提供されている修飾語句

View file

@ -17,7 +17,7 @@ app.on('window-all-closed', function() {
### イベント: 'will-finish-launching'
アプリケーションの基礎起動が終わったときに出力されます。Windows と Linuxでは、 `will-finish-launching` イベントと`ready`イベントは同じです。OS Xでは、`NSApplication`の `applicationWillFinishLaunching` 通知をに相当します。通常、`open-file`と`open-url` 用のリスナーの設定、クラッシュレポートの開始、自動アップデートをします。
アプリケーションの基礎起動が終わったときに出力されます。Windows と Linuxでは、 `will-finish-launching` イベントと`ready`イベントは同じです。macOSでは、`NSApplication`の `applicationWillFinishLaunching` 通知をに相当します。通常、`open-file`と`open-url` 用のリスナーの設定、クラッシュレポートの開始、自動アップデートをします。
ほとんどの場合、 `ready` イベントハンドラーですべてをするべきです。
@ -58,7 +58,7 @@ Electronの初期化が終わった時に出力します。
アプリケーションが終了したときに出力されます。
### イベント: 'open-file' _OS X_
### イベント: 'open-file' _macOS_
戻り値:
@ -71,7 +71,7 @@ Electronの初期化が終わった時に出力します。
Windowsでは、ファイルパスを取得するために、 `process.argv` をパースする必要があります。
### イベント: 'open-url' _OS X_
### イベント: 'open-url' _macOS_
戻り値:
@ -82,7 +82,7 @@ Windowsでは、ファイルパスを取得するために、 `process.argv` を
このイベントをハンドルしたい場合は、`event.preventDefault()`をコールすべきです。
### イベント: 'activate' _OS X_
### イベント: 'activate' _macOS_
戻り値:
@ -237,7 +237,7 @@ gpu プロセスがクラッシュしたときに出力されます。
* `appData` 既定で示すユーザーごとのアプリケーションディレクトリ
* `%APPDATA%` Windows上
* `$XDG_CONFIG_HOME` or `~/.config` Linux上
* `~/Library/Application Support` OS X
* `~/Library/Application Support` macOS上
* `userData` アプリの設定ファイルを格納するディレクトリで、既定では`appData` ディレクトリ配下のアプリ名ディレクトリです
* `temp` 一時ディレクトリ
* `exe` 現在の実行ファイル
@ -274,15 +274,15 @@ gpu プロセスがクラッシュしたときに出力されます。
現在のアプリケーションのロケールを戻します。
### `app.addRecentDocument(path)` _OS X_ _Windows_
### `app.addRecentDocument(path)` _macOS_ _Windows_
* `path` String
最近のドキュメント一覧に`path`を追加します。
この一覧はOSが管理しています。Windowsではタスクバーからこの一覧を見れ、OS Xではdockメニューから見れます。
この一覧はOSが管理しています。Windowsではタスクバーからこの一覧を見れ、macOSではdockメニューから見れます。
### `app.clearRecentDocuments()` _OS X_ _Windows_
### `app.clearRecentDocuments()` _macOS_ _Windows_
最近のドキュメント一覧をクリアします。
@ -321,7 +321,7 @@ The `callback` は、 `app`の`ready` イベントの出力後に実行するこ
プロセスがアプリケーションのプライマリインスタンスでアプリがロードし続けるなら、このメソッドは `false`を戻します。プロセスがほかのインスタンスにパラメーターを送信し、`true`を戻すと、直ちに終了します。
OS Xは、ユーザーがFinderで2つ目のアプリインスタンスを開いたり、`open-file` 、 `open-url`イベントが出力しようとすると、システムが自動的にシングルインスタンスを強制します。しかし、コマンドラインでアプリを開始するとシステムのシングルインスタンスメカニズムは無視されるので、シングルインスタンスを強制するためには、このメソッドを使う必要があります。
macOSは、ユーザーがFinderで2つ目のアプリインスタンスを開いたり、`open-file` 、 `open-url`イベントが出力しようとすると、システムが自動的にシングルインスタンスを強制します。しかし、コマンドラインでアプリを開始するとシステムのシングルインスタンスメカニズムは無視されるので、シングルインスタンスを強制するためには、このメソッドを使う必要があります。
2つ目のインスタンスを起動するとき、メインのインスタンスのウィンドウをアクティブにする例
@ -392,7 +392,7 @@ Chromiumのコマンドダインに引数を追加します。引数は正しく
**Note:** `process.argv`に影響しません。
### `app.dock.bounce([type])` _OS X_
### `app.dock.bounce([type])` _macOS_
* `type` String (optional) - `critical` または `informational`を指定できます。既定では、 `informational`です。
@ -402,37 +402,37 @@ Chromiumのコマンドダインに引数を追加します。引数は正しく
リクエストを示すIDを戻します。
### `app.dock.cancelBounce(id)` _OS X_
### `app.dock.cancelBounce(id)` _macOS_
* `id` Integer
`id`のバウンスをキャンセルします。
### `app.dock.setBadge(text)` _OS X_
### `app.dock.setBadge(text)` _macOS_
* `text` String
dockのバッジエリアで表示する文字列を設定します。
### `app.dock.getBadge()` _OS X_
### `app.dock.getBadge()` _macOS_
dockのバッジ文字列を戻します。
### `app.dock.hide()` _OS X_
### `app.dock.hide()` _macOS_
dock アイコンを隠します。
### `app.dock.show()` _OS X_
### `app.dock.show()` _macOS_
dock アイコンを表示します。
### `app.dock.setMenu(menu)` _OS X_
### `app.dock.setMenu(menu)` _macOS_
* `menu` Menu
アプリケーションの[dock menu][dock-menu]を設定します。
### `app.dock.setIcon(image)` _OS X_
### `app.dock.setIcon(image)` _macOS_
* `image` [NativeImage](native-image.md)

View file

@ -6,9 +6,9 @@
`autoUpdater`は、異なるプラットフォーム用に統一したAPIを提供していますが、それぞれのプラットフォーム上で、まだ多少の差があります。
### OS X
### macOS
OS Xでは、 `autoUpdater` モジュールは、[Squirrel.Mac][squirrel-mac]上に構築されていて、動作させるのに特別な設定が不要であることを意味します。サーバーサイドの要件は、[Server Support][server-support]を読んでください。
macOSでは、 `autoUpdater` モジュールは、[Squirrel.Mac][squirrel-mac]上に構築されていて、動作させるのに特別な設定が不要であることを意味します。サーバーサイドの要件は、[Server Support][server-support]を読んでください。
### Windows
@ -16,7 +16,7 @@ Windowsでは、auto-updaterを使う前に、ユーザーのPCにアプリを
Squirrelで生成されたインストーラーは、`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`のフォーマット(例えば、`com.squirrel.slack.Slack` と `com.squirrel.code.Code`)で[Application User Model ID][app-user-model-id]とショートカットアイコンを作成します。`app.setAppUserModelId`APIで同じIDを使う必要があります。同じIDでないと、Windowsはタスクバーに適切にピン止めすることができません。
サーバーサイドのセットアップは、OS Xと異なります。詳細は、[Squirrel.Windows][squirrel-windows] を参照してください。
サーバーサイドのセットアップは、macOSと異なります。詳細は、[Squirrel.Windows][squirrel-windows] を参照してください。
### Linux

View file

@ -37,7 +37,7 @@ crashReporter.start({
他の`crashReporter`APIを使用する前にこのメソッドをコールする必要があります。
**Note:** OS Xでは、Electronは、WindowsとLinux上の`breakpad` とは異なる、新しい`crashpad`クライアントを使用します。クラッシュ収集機能を有効にするために、メインプロセスや、クラッシュレポートを収集したいそれぞれのレンダラープロセスで、`crashpad`を初期化するために`crashReporter.start`APIをコールする必要があります。
**Note:** macOSでは、Electronは、WindowsとLinux上の`breakpad` とは異なる、新しい`crashpad`クライアントを使用します。クラッシュ収集機能を有効にするために、メインプロセスや、クラッシュレポートを収集したいそれぞれのレンダラープロセスで、`crashpad`を初期化するために`crashReporter.start`APIをコールする必要があります。
### `crashReporter.getLastCrashReport()`

View file

@ -10,7 +10,7 @@ const dialog = require('electron').dialog;
console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));
```
**Note for OS X**: シートとしてダイアログを表示したい場合、唯一しなければならないことは、`browserWindow`パラメーターを参照する`BrowserWindow`を提供することです。
**Note for macOS**: シートとしてダイアログを表示したい場合、唯一しなければならないことは、`browserWindow`パラメーターを参照する`BrowserWindow`を提供することです。
## メソッド
@ -73,7 +73,7 @@ console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', '
* `message` String - メッセージボックスのコンテンツ。
* `detail` String - メッセージの外部情報
* `icon` [NativeImage](native-image.md)
* `cancelId` Integer - ダイアログのボタンをクリックする代わりにユーザーがダイアログをキャンセルしたときに返す値です。既定では、ラベルの "cancel"や"no"を持つボタンのインデックスまたは、そのようなボタンが無ければ0を返します。OS XやWindowsでは、 すでに指定されているかどうかは関係なく、"Cancel"ボタンのインデックスはいつでも `cancelId`が使われます。
* `cancelId` Integer - ダイアログのボタンをクリックする代わりにユーザーがダイアログをキャンセルしたときに返す値です。既定では、ラベルの "cancel"や"no"を持つボタンのインデックスまたは、そのようなボタンが無ければ0を返します。macOSやWindowsでは、 すでに指定されているかどうかは関係なく、"Cancel"ボタンのインデックスはいつでも `cancelId`が使われます。
* `noLink` Boolean - Windowsでは、Electronは、 ("Cancel" または "Yes"のような)共通ボタンである`buttons`の一つを見つけようとし、ダイアログ内のコマンドリンクとして表示します。この挙動が気に入らない場合は、 `noLink``true`に設定できます。
* `callback` Function

View file

@ -11,9 +11,9 @@ const BrowserWindow = require('electron').BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600, frame: false });
```
### OS Xでの別の方法
### macOSでの別の方法
Mac OS X 10.10 Yosemite以降では、Chrome無しのウィンドウを指定する方法があります。`frame`を`false`に設定しタイトルバーとウィンドウコントロールの両方を無効にする代わりに、タイトルバーを隠しコンテンツをフルウィンドウサイズに広げたいけど、標準的なウィンドウ操作用にウィンドウコントロール("トラフィックライト")を維持したいかもしれません。新しい`titleBarStyle`オプションを指定することで、そうできます。
macOS 10.10 Yosemite以降では、Chrome無しのウィンドウを指定する方法があります。`frame`を`false`に設定しタイトルバーとウィンドウコントロールの両方を無効にする代わりに、タイトルバーを隠しコンテンツをフルウィンドウサイズに広げたいけど、標準的なウィンドウ操作用にウィンドウコントロール("トラフィックライト")を維持したいかもしれません。新しい`titleBarStyle`オプションを指定することで、そうできます。
```javascript
var win = new BrowserWindow({ 'titleBarStyle': 'hidden' });

View file

@ -38,7 +38,7 @@
* `minimize` - 現在のウィンドウの最小化
* `close` - 現在のウィンドウを閉じます
OS Xでは、`role`は次の追加の値を取れます:
macOSでは、`role`は次の追加の値を取れます:
* `about` - `orderFrontStandardAboutPanel`動作に紐づけられます
* `hide` - `hide`動作に紐づけられます

View file

@ -208,9 +208,9 @@ Menu.setApplicationMenu(menu);
* `menu` Menu
OS Xで、アプリケーションメニューとして`menu`を設定します。WindowsとLinuxでは、`menu`はそれぞれのウィンドウの上のメニューとして設定されます。
macOSで、アプリケーションメニューとして`menu`を設定します。WindowsとLinuxでは、`menu`はそれぞれのウィンドウの上のメニューとして設定されます。
### `Menu.sendActionToFirstResponder(action)` _OS X_
### `Menu.sendActionToFirstResponder(action)` _macOS_
* `action` String
@ -229,7 +229,7 @@ OS Xで、アプリケーションメニューとして`menu`を設定します
* `browserWindow` BrowserWindow (オプション) - 既定では`null`です。
* `x` Number (オプション) - 既定では -1です。
* `y` Number (**必須** `x` が使われている場合) - 既定では -1です。
* `positioningItem` Number (オプション) _OS X_ - 既定では -1です。
* `positioningItem` Number (オプション) _macOS_ - 既定では -1です。
メニューアイテムのインデックスを指定した座標にマウスカーソルを配置します。
@ -252,13 +252,13 @@ OS Xで、アプリケーションメニューとして`menu`を設定します
メニューのアイテムを収容した配列を取得します。
## OS X アプリケーションメニューの注意事項
## macOS アプリケーションメニューの注意事項
OS Xは、WindowsとLinuxのアプリケーションのメニューとは完全に異なるスタイルを持ち、よりネイティブのようにアプリメニューを作成するのに幾つかの注意事項があります。
macOSは、WindowsとLinuxのアプリケーションのメニューとは完全に異なるスタイルを持ち、よりネイティブのようにアプリメニューを作成するのに幾つかの注意事項があります。
### 標準的なメニュー
OS Xでは、`Services`と`Windows`メニューのように定義された標準的な多くのメニューがあります。標準的なメニューを作成するために、メニューの`role`に次のどれかを設定する必要があり、Electronはそれを受けて標準的なメニューを作成します。
macOSでは、`Services`と`Windows`メニューのように定義された標準的な多くのメニューがあります。標準的なメニューを作成するために、メニューの`role`に次のどれかを設定する必要があり、Electronはそれを受けて標準的なメニューを作成します。
* `window`
* `help`
@ -266,11 +266,11 @@ OS Xでは、`Services`と`Windows`メニューのように定義された標準
### 標準的なメニューアイテムの動作
`About xxx`と`Hide xxx`、`Hide Others`のようないくつかのメニューアイテム用にOS Xは標準的な動作を提供します。メニューアイテムの動作に標準的な動作を設定するために、メニューアイテムの`role`属性を設定すべきです。
`About xxx`と`Hide xxx`、`Hide Others`のようないくつかのメニューアイテム用にmacOSは標準的な動作を提供します。メニューアイテムの動作に標準的な動作を設定するために、メニューアイテムの`role`属性を設定すべきです。
### メインのメニュー名
OS Xでは、設定したラベルに関係なく、アプリケーションの最初のアイテムのラベルはいつもアプリの名前です。変更するために、アプリにバンドルされている`Info.plist`ファイルを修正してアプリの名前を変更する必要があります。詳細は、 [About Information Property List Files][AboutInformationPropertyListFiles] を見てください。
macOSでは、設定したラベルに関係なく、アプリケーションの最初のアイテムのラベルはいつもアプリの名前です。変更するために、アプリにバンドルされている`Info.plist`ファイルを修正してアプリの名前を変更する必要があります。詳細は、 [About Information Property List Files][AboutInformationPropertyListFiles] を見てください。
## メニューアイテムの位置

View file

@ -66,7 +66,7 @@ var appIcon = new Tray('/Users/somebody/images/icon.png');
もっとも一般的なケースは、ライトとダークなメニュバー両方に切り替え可能なメニュバーアイコン用にテンプレート画像を使います。
**Note:** テンプレート画像は、OS Xでのみサポートしています。
**Note:** テンプレート画像は、macOSでのみサポートしています。
テンプレート画像として画像をマークするために、ファイル名の最後に`Template`をつけます。

View file

@ -72,7 +72,7 @@ Windows Store App (appx)として動作中の場合は、値は`true`になり
このプロセスのメインスレッドをハングさせます。
### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_
### `process.setFdLimit(maxDescriptors)` _macOS_ _Linux_
* `maxDescriptors` Integer

View file

@ -63,9 +63,9 @@ __プラットフォームの制限:__
トレイアイコンがクリックされたときに出力されます。
__Note:__ `バウンド` 再生はOS XとWindoesのみで実装されています。
__Note:__ `バウンド` 再生はmacOSとWindoesのみで実装されています。
### イベント: 'right-click' _OS X_ _Windows_
### イベント: 'right-click' _macOS_ _Windows_
* `event` Event
* `altKey` Boolean
@ -80,7 +80,7 @@ __Note:__ `バウンド` 再生はOS XとWindoesのみで実装されていま
トレイアイコンが右クリックされると出力されます。
### イベント: 'double-click' _OS X_ _Windows_
### イベント: 'double-click' _macOS_ _Windows_
* `event` Event
* `altKey` Boolean
@ -107,26 +107,26 @@ __Note:__ `バウンド` 再生はOS XとWindoesのみで実装されていま
タイムアウトもしくはユーザーの操作で閉じて、トレイバルーンがクロースされたときに出力されます。
### イベント: 'drop' _OS X_
### イベント: 'drop' _macOS_
トレイアイコンでアイテムがドラグアンドドロップされたときに出力されます。
### イベント: 'drop-files' _OS X_
### イベント: 'drop-files' _macOS_
* `event`
* `files` Array - ドロップされたアイテムのフルパス
トレイアイコンでファイルがドロップされたときに出力されます。
### イベント: 'drag-enter' _OS X_
### イベント: 'drag-enter' _macOS_
トレイアイコンにドラッグ操作が入ったときに出力されます。
### イベント: 'drag-leave' _OS X_
### イベント: 'drag-leave' _macOS_
トレイアイコンででドラッグ操作が行われたときに出力されます。
### イベント: 'drag-end' _OS X_
### イベント: 'drag-end' _macOS_
トレイ上でドラッグ操作が終了したか、ほかの場所で終了したときに出力されます。
@ -146,11 +146,11 @@ __Note:__ `バウンド` 再生はOS XとWindoesのみで実装されていま
トレイアイコンの`image`を設定します。
### `Tray.setPressedImage(image)` _OS X_
### `Tray.setPressedImage(image)` _macOS_
* `image` [NativeImage](native-image.md)
OS Xで押されたときにトレイアイコンの`image`を設定します。
macOSで押されたときにトレイアイコンの`image`を設定します。
### `Tray.setToolTip(toolTip)`
@ -158,13 +158,13 @@ OS Xで押されたときにトレイアイコンの`image`を設定します。
トレイアイコン用のホバーテキストを設定します。
### `Tray.setTitle(title)` _OS X_
### `Tray.setTitle(title)` _macOS_
* `title` String
ステータスバーで、トレイアイコンのわきに表示するタイトルを設定します。
### `Tray.setHighlightMode(highlight)` _OS X_
### `Tray.setHighlightMode(highlight)` _macOS_
* `highlight` Boolean
@ -179,7 +179,7 @@ OS Xで押されたときにトレイアイコンの`image`を設定します。
トレイバルーンを表示します。
### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_
### `Tray.popUpContextMenu([menu, position])` _macOS_ _Windows_
* `menu` Menu (optional)
* `position` Object (optional) - ポップアップ位置

View file

@ -1,9 +1,9 @@
# アプリケーションの配布
Electronでアプリケーションを配布するために、アプリケーションを`app` という名前のディレクトリにし、Electronのリソースディレクトリ(OS X では
Electronでアプリケーションを配布するために、アプリケーションを`app` という名前のディレクトリにし、Electronのリソースディレクトリ(macOS では
`Electron.app/Contents/Resources/` 、Linux と Windows では `resources/`)配下に置くべきです,
OS X:
macOS:
```text
electron/Electron.app/Contents/Resources/app/
@ -29,7 +29,7 @@ electron/resources/app
`app` フォルダの代わりに `asar` アーカイブを使用するためには、アーカイブファイルを `app.asar` という名前に変更し、Electron のリソースディレクトリに以下のように配置する必要があります。すると、Electron はアーカイブを読み込もうとし、それを開始します。
OS X:
macOS:
```text
electron/Electron.app/Contents/Resources/
@ -54,7 +54,7 @@ Electronにバンドルした後、ユーザーに配布する前に、 Electron
`electron.exe`を任意の名前に変更でき、[rcedit](https://github.com/atom/rcedit)
のようなツールでアイコンやその他の情報を編集できます。
### OS X
### macOS
`Electron.app` を任意の名前に変更でき、次のファイルの `CFBundleDisplayName``CFBundleIdentifier``CFBundleName`のフィールドの名前を変更する必要があります。

View file

@ -4,7 +4,7 @@
このガイドでは、Electron APIでデスクトップ環境にアプリケーションを統合する方法を説明します。
## 通知 (Windows, Linux, OS X)
## 通知 (Windows, Linux, macOS)
3つのオペレーティングシステム全てで、アプリケーションからユーザーに通知を送る手段が提供されています。通知を表示するためにオペレーティングシステムのネイティブ通知APIを使用しする[HTML5 Notification API](https://notifications.spec.whatwg.org/)で、Electronは、開発者に通知を送ることができます。
@ -36,15 +36,15 @@ Model ID][app-user-model-id]で、アプリへのショートカットはスタ
通知は、`libnotify`を使用して送信されます。[デスクトップ通知仕様][notification-spec]に対応したデスクトップ環境上Cinnamon、Enlightenment、Unity、GNOME、KDEなどで通知を表示できます。
### OS X
### macOS
通知は、そのままOS Xに通知されます。しかし、[通知に関するAppleのヒューマンインターフェイスガイドライン英語版](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html)を知っておくべきです。
通知は、そのままmacOSに通知されます。しかし、[通知に関するAppleのヒューマンインターフェイスガイドライン英語版](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html)を知っておくべきです。
通知は、256バイトサイズに制限されており、制限を超えていた場合、通知が破棄されます。
## 最近のドキュメント (Windows と OS X)
## 最近のドキュメント (Windows と macOS)
Windows と OS Xは、ジャンプリストやドックメニュー経由で、アプリケーションが開いた最近のドキュメント一覧に簡単にアクセスできます。
Windows と macOSは、ジャンプリストやドックメニュー経由で、アプリケーションが開いた最近のドキュメント一覧に簡単にアクセスできます。
__JumpList:__
@ -72,19 +72,19 @@ Windows で、この機能を使用できるようにするために、アプリ
ユーザーがジャンプリストからファイルをクリックしたとき、アプリケーションの新しいインスタンスは、コマンドライン引数にファイルのパスを渡して開始します。
### OS X 留意点
### macOS 留意点
ファイルが最近のドキュメントメニューからリクエストされた時、 `app` モジュールの `open-file` イベントが発行されます。
## ドックメニュー (OS X)のカスタマイズ
## ドックメニュー (macOS)のカスタマイズ
通常アプリケーションで使用する共通機能用のショートカットを含める、ドック用のカスタムメニューをOS Xでは指定できます。
通常アプリケーションで使用する共通機能用のショートカットを含める、ドック用のカスタムメニューをmacOSでは指定できます。
__Dock menu of Terminal.app:__
<img src="https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png" height="354" width="341" >
カスタムドックメニューを設定するために、OS Xのみに提供されている `app.dock.setMenu` APIを使用できます。
カスタムドックメニューを設定するために、macOSのみに提供されている `app.dock.setMenu` APIを使用できます。
```javascript
const electron = require('electron');
@ -115,7 +115,7 @@ __Internet Explorerのタスク:__
![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png)
実際のメニューであるOS Xのドックメニューとは異なり、ユーザーがタスクをクリックしたとき、Windowsではユーザータスクはアプリケーションのショートカットのように動作し、プログラムは指定された引数を実行します。
実際のメニューであるmacOSのドックメニューとは異なり、ユーザーがタスクをクリックしたとき、Windowsではユーザータスクはアプリケーションのショートカットのように動作し、プログラムは指定された引数を実行します。
アプリケーション用のユーザータスクを設定するために、[app.setUserTasks][setusertaskstasks] APIを使用できます:
@ -192,11 +192,11 @@ __Audaciousのランチャーショートカット:__
![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png)
## タスクバーの進行状況バー (Windows, OS X, Unity)
## タスクバーの進行状況バー (Windows, macOS, Unity)
Windowsでは、タスクバーボタンは、進行状況バーを表示するのに使えます。ウィンドウを切り替えることなくウィンドウの進行状況情報をユーザーに提供することができます。
OS Xではプログレスバーはドックアイコンの一部として表示されます。
macOSではプログレスバーはドックアイコンの一部として表示されます。
Unity DEは、ランチャーに進行状況バーの表示をするのと同様の機能を持っています。
__タスクバーボタン上の進行状況バー:__
@ -227,9 +227,9 @@ let win = new BrowserWindow({...});
win.setOverlayIcon('path/to/overlay.png', 'Description for overlay');
```
## Windowのファイル表示 (OS X)
## Windowのファイル表示 (macOS)
OS Xでは、ウィンドウがrepresented fileを設定でき、タイトルバー上にファイルのアイコンを表示でき、タイトル上でCommand-クリックまたはControl-クリックをすると、パスがポップアップ表示されます。
macOSでは、ウィンドウがrepresented fileを設定でき、タイトルバー上にファイルのアイコンを表示でき、タイトル上でCommand-クリックまたはControl-クリックをすると、パスがポップアップ表示されます。
ウィンドウの編集状態を設定できるように、このウィンドウのドキュメントが変更されたかどうかをファイルのアイコンで示せます。

View file

@ -84,7 +84,7 @@ codesign -s "$APP_KEY" -f --entitlements parent.plist "$APP_PATH"
productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"
```
OS Xでのアプリのサンドボックス化を行うことが初めてなら、Appleの[Enabling App Sandbox][enable-app-sandbox]を通読し、基本的な考え方を確認してから、、エンタイトルメントファイルにアプリに必要なパーミッションキーを追加します。
macOSでのアプリのサンドボックス化を行うことが初めてなら、Appleの[Enabling App Sandbox][enable-app-sandbox]を通読し、基本的な考え方を確認してから、、エンタイトルメントファイルにアプリに必要なパーミッションキーを追加します。
### Appをアップロードする。

View file

@ -86,14 +86,14 @@ app.on('ready', createWindow);
// すべてのウィンドウが閉じられた時にアプリケーションを終了する。
app.on('window-all-closed', () => {
// OS Xでは、Cmd + Q(終了)をユーザーが実行するまではウィンドウが全て閉じられても終了しないでおく。
// macOSでは、Cmd + Q(終了)をユーザーが実行するまではウィンドウが全て閉じられても終了しないでおく。
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// OS X では、ドックをクリックされた時にウィンドウがなければ新しく作成する。
// macOS では、ドックをクリックされた時にウィンドウがなければ新しく作成する。
if (win === null) {
createWindow();
}
@ -157,7 +157,7 @@ $ .\electron\electron.exe your-app\
$ ./electron/electron your-app/
```
#### OS X
#### macOS
```bash
$ ./Electron.app/Contents/MacOS/Electron your-app/

View file

@ -2,9 +2,9 @@
Electronでは次のプラットフォームをサポートします。
### OS X
### macOS
OS X用に提供しているバイナリは64bitのみで、サポートするOS Xのバージョンは、OS X 10.9 以降です。
macOS用に提供しているバイナリは64bitのみで、サポートするmacOSのバージョンは、macOS 10.9 以降です。
### Windows

View file

@ -5,7 +5,7 @@ Electronは、Pepper Flashプラグインをサポートしています。Electr
## Flash プラグインのコピー準備
OS XとLinuxでは、Pepper Flashプラグインの詳細は、Chromeブラウザーで、`chrome://plugins` にアクセスして確認できます。そこで表示されるパスとバージョンは、ElectronのPepper Flashサポートに役立ちます。それを別のパスにコピーすることができます。
macOSとLinuxでは、Pepper Flashプラグインの詳細は、Chromeブラウザーで、`chrome://plugins` にアクセスして確認できます。そこで表示されるパスとバージョンは、ElectronのPepper Flashサポートに役立ちます。それを別のパスにコピーすることができます。
## Electron スイッチの追加
@ -16,7 +16,7 @@ OS XとLinuxでは、Pepper Flashプラグインの詳細は、Chromeブラウ
```javascript
// Specify flash path.
// On Windows, it might be /path/to/pepflashplayer.dll
// On OS X, /path/to/PepperFlashPlayer.plugin
// On macOS, /path/to/PepperFlashPlayer.plugin
// On Linux, /path/to/libpepflashplayer.so
app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so');

View file

@ -8,13 +8,13 @@ Electronは、ライセンス的な理由でWidevine CDMプラグインは同梱
__Note:__ Chromeブラウザのメジャーバージョンは、Electronが使用するChromeバージョンと同じでなければなりません。そうでなければ、プラグインは、`navigator.plugins`経由でロードされて表示されるにも関わらず動作しません。
### Windows & OS X
### Windows & macOS
Chromeブラウザーで、`chrome://components/`を開き、 `WidevineCdm` を探し、それが最新であることを確認し、`APP_DATA/Google/Chrome/WidevineCDM/VERSION/_platform_specific/PLATFORM_ARCH/`ディレクトリからすべてのプラグインバイナリを探します。
`APP_DATA` は、アプリデータを格納するシステムロケーションです。Windowsでは`%LOCALAPPDATA%`、OS Xでは`~/Library/Application Support`です。`VERSION` は、Widevine CDM プラグインのバージョン文字列で、 `1.4.8.866`のような文字列が格納されます。`PLATFORM` は、 `mac``win`です。`ARCH` は `x86``x64`です。
`APP_DATA` は、アプリデータを格納するシステムロケーションです。Windowsでは`%LOCALAPPDATA%`、macOSでは`~/Library/Application Support`です。`VERSION` は、Widevine CDM プラグインのバージョン文字列で、 `1.4.8.866`のような文字列が格納されます。`PLATFORM` は、 `mac``win`です。`ARCH` は `x86``x64`です。
Windowsでは、`widevinecdm.dll` と `widevinecdmadapter.dll`が必要で、OS Xでは、`libwidevinecdm.dylib` と `widevinecdmadapter.plugin`です。任意の場所にコピーできますが、一緒に配置する必要があります。
Windowsでは、`widevinecdm.dll` と `widevinecdmadapter.dll`が必要で、macOSでは、`libwidevinecdm.dylib` と `widevinecdmadapter.plugin`です。任意の場所にコピーできますが、一緒に配置する必要があります。
### Linux
@ -32,7 +32,7 @@ __Note:__ `widevinecdmadapter` バイナリはElectronにパスが通ってい
```javascript
// You have to pass the filename of `widevinecdmadapter` here, it is
// * `widevinecdmadapter.plugin` on OS X,
// * `widevinecdmadapter.plugin` on macOS,
// * `libwidevinecdmadapter.so` on Linux,
// * `widevinecdmadapter.dll` on Windows.
app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevinecdmadapter.plugin');

View file

@ -6,7 +6,7 @@ URL에 포함되어 있습니다. 만약 그렇지 않다면, 아마 현재 보
수 있습니다. 또한 GitHub 인터페이스의 "Switch branches/tags" 드롭다운 메뉴에서도
사용 중인 Electron 버전으로 변경할 수 있습니다.
**역주:** 한국어 번역 문서는 `atom.io`에 반영되어 있지 않습니다. 한국어 번역 문서는
**역주:** 한국어 번역 문서는 `atom.io`에 반영되어 있지 않습니다. 한국어 번역 문서는
현재 `upstream` 원본 문서의 변경에 따라 최대한 문서의 버전을 맞추려고 노력하고 있지만
가끔 누락된 번역이 존재할 수 있습니다.
@ -22,10 +22,10 @@ Electron에 대해 자주 묻는 질문이 있습니다. 이슈를 생성하기
* [지원하는 플랫폼](tutorial/supported-platforms.md)
* [보안](tutorial/security.md)
* [Electron 버전 관리](tutorial/electron-versioning.md)
* [플리케이션 배포](tutorial/application-distribution.md)
* [Mac 앱스토어 플리케이션 제출 가이드](tutorial/mac-app-store-submission-guide.md)
* [플리케이션 배포](tutorial/application-distribution.md)
* [Mac 앱스토어 플리케이션 제출 가이드](tutorial/mac-app-store-submission-guide.md)
* [Windows 스토어 가이드](tutorial/windows-store-guide.md)
* [플리케이션 패키징](tutorial/application-packaging.md)
* [플리케이션 패키징](tutorial/application-packaging.md)
* [네이티브 Node 모듈 사용하기](tutorial/using-native-node-modules.md)
* [메인 프로세스 디버깅하기](tutorial/debugging-main-process.md)
* [Selenium 과 WebDriver 사용하기](tutorial/using-selenium-and-webdriver.md)
@ -93,7 +93,7 @@ Electron에 대해 자주 묻는 질문이 있습니다. 이슈를 생성하기
* [소스 코드 디렉터리 구조](development/source-code-directory-structure.md)
* [NW.js(node-webkit)와 기술적으로 다른점](development/atom-shell-vs-node-webkit.md)
* [빌드 시스템 개요](development/build-system-overview.md)
* [빌드 설명서 (OS X)](development/build-instructions-osx.md)
* [빌드 설명서 (macOS)](development/build-instructions-osx.md)
* [빌드 설명서 (Windows)](development/build-instructions-windows.md)
* [빌드 설명서 (Linux)](development/build-instructions-linux.md)
* [디버그 설명서 (Windows)](development/debug-instructions-windows.md)

View file

@ -12,13 +12,13 @@ Accelerator는 `+` 문자를 통해 여러 혼합키와 키코드를 결합할
## 플랫폼에 관련하여 주의할 점
Linux와 Windows에서는 `Command`키가 없으므로 작동하지 않습니다. 대신에
`CommandOrControl`을 사용하면 OS X`Command`와 Linux, Windows의 `Control` 모두
`CommandOrControl`을 사용하면 macOS의 `Command`와 Linux, Windows의 `Control` 모두
지원할 수 있습니다.
`Option` 대신 `Alt`을 사용하는게 좋습니다. `Option` 키는 OS X에만 있으므로
`Option` 대신 `Alt`을 사용하는게 좋습니다. `Option` 키는 macOS에만 있으므로
모든 플랫폼에서 사용할 수 있는 `Alt` 키를 권장합니다.
`Super`키는 Windows와 Linux 에서는 `윈도우`키를, OS X에서는 `Cmd`키로 맵핑됩니다.
`Super`키는 Windows와 Linux 에서는 `윈도우`키를, macOS에서는 `Cmd`키로 맵핑됩니다.
## 사용 가능한 혼합키

View file

@ -1,8 +1,8 @@
# app
> 플리케이션의 이벤트 생명주기를 제어합니다.
> 플리케이션의 이벤트 생명주기를 제어합니다.
밑의 예시는 마지막 윈도우가 종료되었을 때, 플리케이션을 종료시키는 예시입니다:
밑의 예시는 마지막 윈도우가 종료되었을 때, 플리케이션을 종료시키는 예시입니다:
```javascript
const {app} = require('electron');
@ -17,9 +17,9 @@ app.on('window-all-closed', () => {
### Event: 'will-finish-launching'
플리케이션이 기본적인 시작 준비를 마치면 발생하는 이벤트입니다.
플리케이션이 기본적인 시작 준비를 마치면 발생하는 이벤트입니다.
Windows, Linux 운영체제에서의 `will-finish-launching` 이벤트는 `ready` 이벤트와
동일합니다. OS X에서의 이벤트는 `NSApplication`
동일합니다. macOS에서의 이벤트는 `NSApplication`
`applicationWillFinishLaunching`에 대한 알림으로 표현됩니다. 대개 이곳에서
`open-file``open-url` 이벤트 리스너를 설정하고 crash reporter와 auto updater를
시작합니다.
@ -41,8 +41,8 @@ Electron은 먼저 모든 윈도우의 종료를 시도하고 `will-quit` 이벤
그리고 `will-quit` 이벤트가 발생했을 땐 `window-all-closed` 이벤트가 발생하지
않습니다.
**역주:** 이 이벤트는 말 그대로 현재 어플리케이션에서 윈도우만 완전히 종료됬을 때
발생하는 이벤트입니다. 따라서 플리케이션을 완전히 종료하려면 이 이벤트에서
**역자주:** 이 이벤트는 말 그대로 현재 애플리케이션에서 윈도우만 완전히 종료됬을 때
발생하는 이벤트입니다. 따라서 플리케이션을 완전히 종료하려면 이 이벤트에서
`app.quit()`를 호출해 주어야 합니다.
### Event: 'before-quit'
@ -51,9 +51,9 @@ Returns:
* `event` Event
플리케이션 윈도우들이 닫히기 시작할 때 발생하는 이벤트입니다.
플리케이션 윈도우들이 닫히기 시작할 때 발생하는 이벤트입니다.
`event.preventDefault()` 호출은 이벤트의 기본 동작을 방지하기 때문에
이를 통해 플리케이션의 종료를 방지할 수 있습니다.
이를 통해 플리케이션의 종료를 방지할 수 있습니다.
### Event: 'will-quit'
@ -61,8 +61,8 @@ Returns:
* `event` Event
모든 윈도우들이 종료되고 플리케이션이 종료되기 시작할 때 발생하는 이벤트입니다.
`event.preventDefault()` 호출을 통해 플리케이션의 종료를 방지할 수 있습니다.
모든 윈도우들이 종료되고 플리케이션이 종료되기 시작할 때 발생하는 이벤트입니다.
`event.preventDefault()` 호출을 통해 플리케이션의 종료를 방지할 수 있습니다.
`will-quit``window-all-closed` 이벤트의 차이점을 확인하려면 `window-all-closed`
이벤트의 설명을 참고하세요.
@ -74,51 +74,51 @@ Returns:
* `event` Event
* `exitCode` Integer
플리케이션이 종료될 때 발생하는 이벤트입니다.
플리케이션이 종료될 때 발생하는 이벤트입니다.
### Event: 'open-file' _OS X_
### Event: 'open-file' _macOS_
Returns:
* `event` Event
* `path` String
사용자가 플리케이션을 통해 파일을 열고자 할 때 발생하는 이벤트입니다.
사용자가 플리케이션을 통해 파일을 열고자 할 때 발생하는 이벤트입니다.
`open-file` 이벤트는 보통 플리케이션이 열려 있을 때 OS가 파일을 열기 위해
플리케이션을 재사용할 때 발생합니다. 이 이벤트는 파일을 dock에 떨어트릴 때,
플리케이션이 실행되기 전에도 발생합니다. 따라서 이 이벤트를 제대로 처리하려면
`open-file` 이벤트 핸들러를 플리케이션이 시작하기 전에 등록해 놓았는지 확실히
`open-file` 이벤트는 보통 플리케이션이 열려 있을 때 OS가 파일을 열기 위해
플리케이션을 재사용할 때 발생합니다. 이 이벤트는 파일을 dock에 떨어트릴 때,
플리케이션이 실행되기 전에도 발생합니다. 따라서 이 이벤트를 제대로 처리하려면
`open-file` 이벤트 핸들러를 플리케이션이 시작하기 전에 등록해 놓았는지 확실히
확인해야 합니다. (`ready` 이벤트가 발생하기 전에)
이 이벤트를 처리할 땐 반드시 `event.preventDefault()`를 호출해야 합니다.
Windows에선 `process.argv` (메인 프로세스에서)를 통해 파일 경로를 얻을 수 있습니다.
### Event: 'open-url' _OS X_
### Event: 'open-url' _macOS_
Returns:
* `event` Event
* `url` String
유저가 플리케이션을 통해 URL을 열고자 할 때 발생하는 이벤트입니다.
유저가 플리케이션을 통해 URL을 열고자 할 때 발생하는 이벤트입니다.
플리케이션에서 URL을 열기 위해 반드시 URL 스킴이 등록되어 있어야 합니다.
플리케이션에서 URL을 열기 위해 반드시 URL 스킴이 등록되어 있어야 합니다.
이 이벤트를 처리할 땐 반드시 `event.preventDefault()`를 호출해야 합니다.
### Event: 'activate' _OS X_
### Event: 'activate' _macOS_
Returns:
* `event` Event
* `hasVisibleWindows` Boolean
플리케이션이 활성화 되었을 때 발생하는 이벤트입니다. 이 이벤트는 사용자가
플리케이션의 dock 아이콘을 클릭했을 때 주로 발생합니다.
플리케이션이 활성화 되었을 때 발생하는 이벤트입니다. 이 이벤트는 사용자가
플리케이션의 dock 아이콘을 클릭했을 때 주로 발생합니다.
### Event: 'continue-activity' _OS X_
### Event: 'continue-activity' _macOS_
Returns:
@ -131,9 +131,9 @@ Returns:
발생하는 이벤트입니다. 이 이벤트를 처리하려면 반드시 `event.preventDefault()`
호출해야 합니다.
사용자 activity는 activity의 소스 플리케이션과 같은 개발자 팀 ID를 가지는
플리케이션 안에서만 재개될 수 있고, activity의 타입을 지원합니다. 지원하는
activity의 타입은 플리케이션 `Info.plist``NSUserActivityTypes` 키에 열거되어
사용자 activity는 activity의 소스 플리케이션과 같은 개발자 팀 ID를 가지는
플리케이션 안에서만 재개될 수 있고, activity의 타입을 지원합니다. 지원하는
activity의 타입은 플리케이션 `Info.plist``NSUserActivityTypes` 키에 열거되어
있습니다.
### Event: 'browser-window-blur'
@ -154,7 +154,7 @@ Returns:
[browserWindow](browser-window.md)에 대한 포커스가 발생했을 때 발생하는 이벤트입니다.
**역주:** _포커스_ 는 창을 클릭해서 활성화 시켰을 때를 말합니다.
**역주:** _포커스_ 는 창을 클릭해서 활성화 시켰을 때를 말합니다.
### Event: 'browser-window-created'
@ -165,6 +165,15 @@ Returns:
새로운 [browserWindow](browser-window.md)가 생성되었을 때 발생하는 이벤트입니다.
### Event: 'web-contents-created'
Returns:
* `event` Event
* `webContents` WebContents
새로운 [webContents](web-contents.md)가 생성되었을 때 발생하는 이벤트입니다.
### Event: 'certificate-error'
Returns:
@ -265,7 +274,7 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입
모든 윈도우 종료를 시도합니다. `before-quit` 이벤트가 먼저 발생합니다.
모든 윈도우가 성공적으로 종료되면 `will-quit` 이벤트가 발생하고 기본 동작에 따라
플리케이션이 종료됩니다.
플리케이션이 종료됩니다.
이 함수는 모든 `beforeunload``unload` 이벤트 핸들러가 제대로 실행됨을 보장합니다.
`beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 종료가 취소 될 수
@ -275,7 +284,7 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입
* `exitCode` Integer
`exitCode`와 함께 플리케이션을 즉시 종료합니다.
`exitCode`와 함께 플리케이션을 즉시 종료합니다.
모든 윈도우는 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와
`will-quit` 이벤트가 발생하지 않습니다.
@ -286,20 +295,20 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입
* `args` Array (optional)
* `execPath` String (optional)
현재 인스턴스가 종료되면 플리케이션을 재시작합니다.
현재 인스턴스가 종료되면 플리케이션을 재시작합니다.
기본적으로 새 인스턴스는 같은 작업 디렉토리의 것과 함께 현재 인스턴스의 명령줄 인수를
사용합니다. 만약 `args`가 지정되면, `args`가 기본 명령줄 인수 대신에 전달됩니다.
`execPath`가 지정되면, 현재 플리케이션 대신 `execPath`가 실행됩니다.
`execPath`가 지정되면, 현재 플리케이션 대신 `execPath`가 실행됩니다.
참고로 이 메서드는 어플리케이션을 종료하지 않으며, 어플리케이션을 다시 시작시키려면
참고로 이 메서드는 애플리케이션을 종료하지 않으며, 애플리케이션을 다시 시작시키려면
`app.relaunch`를 호출한 후 `app.quit` 또는 `app.exit`를 실행해주어야 합니다.
`app.relaunch`가 여러 번 호출되면, 현재 인스턴스가 종료된 후 여러 인스턴스가
시작됩니다.
다음은 현재 인스턴스를 즉시 종료시킨 후 새로운 명령줄 인수를 추가하여 새
인스턴스의 플리케이션을 실행하는 예시입니다:
인스턴스의 플리케이션을 실행하는 예시입니다:
```javascript
app.relaunch({args: process.argv.slice(1) + ['--relaunch']})
@ -308,20 +317,20 @@ app.exit(0)
### `app.focus()`
Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. OS X에선, 어플리케이션을 활성화
앱 상태로 만듭니다. Windows에선, 플리케이션의 첫 윈도우에 포커스 됩니다.
Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. macOS에선, 애플리케이션을 활성화
앱 상태로 만듭니다. Windows에선, 플리케이션의 첫 윈도우에 포커스 됩니다.
### `app.hide()` _OS X_
### `app.hide()` _macOS_
최소화를 하지 않고 플리케이션의 모든 윈도우들을 숨깁니다.
최소화를 하지 않고 플리케이션의 모든 윈도우들을 숨깁니다.
### `app.show()` _OS X_
### `app.show()` _macOS_
숨긴 플리케이션 윈도우들을 다시 보이게 만듭니다. 자동으로 포커스되지 않습니다.
숨긴 플리케이션 윈도우들을 다시 보이게 만듭니다. 자동으로 포커스되지 않습니다.
### `app.getAppPath()`
현재 플리케이션의 디렉터리를 반환합니다.
현재 플리케이션의 디렉터리를 반환합니다.
### `app.getPath(name)`
@ -330,17 +339,17 @@ Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. OS X에
`name`에 관련한 특정 디렉터리 또는 파일의 경로를 반환합니다.
경로를 가져오는 데 실패할 경우 `Error`를 반환합니다.
**역주:** 이 메서드는 운영체제에서 지정한 특수 디렉터리를 가져오는데 사용할 수 있습니다.
**역주:** 이 메서드는 운영체제에서 지정한 특수 디렉터리를 가져오는데 사용할 수 있습니다.
`name`은 다음 목록에 있는 경로 중 하나를 선택해 사용할 수 있습니다:
* `home` - 사용자의 홈 디렉터리.
* `appData` - 각 사용자의 플리케이션 데이터 디렉터리. 기본 경로는 다음과 같습니다:
* `appData` - 각 사용자의 플리케이션 데이터 디렉터리. 기본 경로는 다음과 같습니다:
* `%APPDATA%` - Windows
* `$XDG_CONFIG_HOME` 또는 `~/.config` - Linux
* `~/Library/Application Support` - OS X
* `userData` - 플리케이션의 설정을 저장하는 디렉터리.
이 디렉터리는 기본적으로 `appData`플리케이션 이름으로 생성된 폴더가 지정됩니다.
* `~/Library/Application Support` - macOS
* `userData` - 플리케이션의 설정을 저장하는 디렉터리.
이 디렉터리는 기본적으로 `appData`플리케이션 이름으로 생성된 폴더가 지정됩니다.
* `temp` - 임시 폴더 디렉터리.
* `userDesktop` - 현재 사용자의 데스트탑 디렉터리.
* `exe` - 현재 실행중인 Electron 바이너리 파일.
@ -351,6 +360,7 @@ Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. OS X에
* `music` - 사용자의 음악 디렉터리.
* `pictures` - 사용자의 사진 디렉터리.
* `videos` - 사용자의 동영상 디렉터리.
* `pepperFlashSystemPlugin` - 시스템 버전의 Pepper Flash 플러그인의 전체 경로.
### `app.setPath(name, path)`
@ -369,49 +379,49 @@ Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. OS X에
### `app.getVersion()`
로드된 플리케이션의 버전을 반환합니다.
로드된 플리케이션의 버전을 반환합니다.
만약 `package.json` 파일에서 플리케이션의 버전을 찾을 수 없는 경우, 현재 번들 또는
만약 `package.json` 파일에서 플리케이션의 버전을 찾을 수 없는 경우, 현재 번들 또는
실행 파일의 버전을 반환합니다.
### `app.getName()`
`package.json`에서 기술된 현재 플리케이션의 이름을 반환합니다.
`package.json`에서 기술된 현재 플리케이션의 이름을 반환합니다.
npm 모듈 규칙에 따라 대부분의 경우 `package.json``name` 필드는 소문자 이름을
사용합니다. 하지만 Electron은 `name`대신 `productName` 필드를 주로 사용하기 때문에
반드시 이 필드도 같이 지정해야 합니다. 이 필드는 맨 앞글자가 대문자인 플리케이션
반드시 이 필드도 같이 지정해야 합니다. 이 필드는 맨 앞글자가 대문자인 플리케이션
전체 이름을 지정해야 합니다.
### `app.setName(name)`
* `name` String
현재 플리케이션의 이름을 덮어씌웁니다.
현재 플리케이션의 이름을 덮어씌웁니다.
### `app.getLocale()`
현재 플리케이션의 [로케일](https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%BC%80%EC%9D%BC)을
현재 플리케이션의 [로케일](https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%BC%80%EC%9D%BC)을
반환합니다.
**참고:** 패키징된 앱을 배포할 때, `locales` 폴더도 같이 배포해야 합니다.
**참고:** Windows에선 `ready` 이벤트가 발생한 이후에 이 메서드를 호출해야 합니다.
### `app.addRecentDocument(path)` _OS X_ _Windows_
### `app.addRecentDocument(path)` _macOS_ _Windows_
* `path` String
최근 문서 목록에 `path`를 추가합니다.
이 목록은 OS에 의해 관리됩니다. 최근 문서 목록은 Windows의 경우 작업 표시줄에서 찾을
수 있고, OS X의 경우 dock 메뉴에서 찾을 수 있습니다.
수 있고, macOS의 경우 dock 메뉴에서 찾을 수 있습니다.
### `app.clearRecentDocuments()` _OS X_ _Windows_
### `app.clearRecentDocuments()` _macOS_ _Windows_
최근 문서 목록을 모두 비웁니다.
### `app.setAsDefaultProtocolClient(protocol)` _OS X_ _Windows_
### `app.setAsDefaultProtocolClient(protocol)` _macOS_ _Windows_
* `protocol` String - 프로토콜의 이름, `://` 제외. 만약 앱을 통해 `electron://`
같은 링크를 처리하고 싶다면, 이 메서드에 `electron` 인수를 담아 호출하면 됩니다.
@ -419,31 +429,31 @@ npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드
이 메서드는 지정한 프로토콜(URI scheme)에 대해 현재 실행파일을 기본 핸들러로
등록합니다. 이를 통해 운영체제와 더 가깝게 통합할 수 있습니다. 한 번 등록되면,
`your-protocol://`과 같은 모든 링크에 대해 호출시 현재 실행 파일이 실행됩니다.
모든 링크, 프로토콜을 포함하여 플리케이션의 인수로 전달됩니다.
모든 링크, 프로토콜을 포함하여 플리케이션의 인수로 전달됩니다.
**참고:** OS X에선, 어플리케이션의 `info.plist`에 등록해둔 프로토콜만 사용할 수
**참고:** macOS에선, 애플리케이션의 `info.plist`에 등록해둔 프로토콜만 사용할 수
있습니다. 이는 런타임에서 변경될 수 없습니다. 이 파일은 간단히 텍스트 에디터를
사용하거나, 플리케이션을 빌드할 때 스크립트가 생성되도록 할 수 있습니다. 자세한
사용하거나, 플리케이션을 빌드할 때 스크립트가 생성되도록 할 수 있습니다. 자세한
내용은 [Apple의 참조 문서][CFBundleURLTypes]를 확인하세요.
이 API는 내부적으로 Windows 레지스트리와 LSSetDefaultHandlerForURLScheme를 사용합니다.
### `app.removeAsDefaultProtocolClient(protocol)` _OS X_ _Windows_
### `app.removeAsDefaultProtocolClient(protocol)` _macOS_ _Windows_
* `protocol` String - 프로토콜의 이름, `://` 제외.
이 메서드는 현재 실행파일이 지정한 프로토콜(URI scheme)에 대해 기본 핸들러인지를
확인합니다. 만약 그렇다면, 이 메서드는 앱을 기본 핸들러에서 제거합니다.
### `app.isDefaultProtocolClient(protocol)` _OS X_ _Windows_
### `app.isDefaultProtocolClient(protocol)` _macOS_ _Windows_
* `protocol` String - `://`를 제외한 프로토콜의 이름.
이 메서드는 현재 실행 파일이 지정한 프로토콜에 대해 기본 동작인지 확인합니다. (URI
스킴) 만약 그렇다면 `true`를 반환하고 아닌 경우 `false`를 반환합니다.
**참고:** OS X에선, 응용 프로그램이 프로토콜에 대한 기본 프로토콜 동작으로
등록되었는지를 확인하기 위해 이 메서드를 사용할 수 있습니다. 또한 OS X에서
**참고:** macOS에선, 응용 프로그램이 프로토콜에 대한 기본 프로토콜 동작으로
등록되었는지를 확인하기 위해 이 메서드를 사용할 수 있습니다. 또한 macOS에서
`~/Library/Preferences/com.apple.LaunchServices.plist`를 확인하여 검증할 수도
있습니다. 자세한 내용은 [Apple의 참조 문서][LSCopyDefaultHandlerForURLScheme]를
참고하세요.
@ -460,13 +470,13 @@ Windows에서 사용할 수 있는 JumpList의 [Tasks][tasks] 카테고리에 `t
`Task` Object:
* `program` String - 실행할 프로그램의 경로.
보통 현재 작동중인 플리케이션의 경로인 `process.execPath`를 지정합니다.
보통 현재 작동중인 플리케이션의 경로인 `process.execPath`를 지정합니다.
* `arguments` String - `program`이 실행될 때 사용될 명령줄 인수.
* `title` String - JumpList에 표시할 문자열.
* `description` String - 이 작업에 대한 설명.
* `iconPath` String - JumpList에 표시될 아이콘의 절대 경로.
아이콘을 포함하고 있는 임의의 리소스 파일을 사용할 수 있습니다.
보통 플리케이션의 아이콘을 그대로 사용하기 위해 `process.execPath`를 지정합니다.
보통 플리케이션의 아이콘을 그대로 사용하기 위해 `process.execPath`를 지정합니다.
* `iconIndex` Integer - 아이콘 파일의 인덱스. 만약 아이콘 파일이 두 개 이상의
아이콘을 가지고 있을 경우, 사용할 아이콘의 인덱스를 이 옵션으로 지정해 주어야 합니다.
단, 아이콘을 하나만 포함하고 있는 경우 0을 지정하면 됩니다.
@ -475,38 +485,38 @@ Windows에서 사용할 수 있는 JumpList의 [Tasks][tasks] 카테고리에 `t
* `callback` Function
현재 플리케이션을 **Single Instance Application** 으로 만들어줍니다.
이 메서드는 플리케이션이 여러 번 실행됐을 때 다중 인스턴스가 생성되는 대신 한 개의
현재 플리케이션을 **Single Instance Application** 으로 만들어줍니다.
이 메서드는 플리케이션이 여러 번 실행됐을 때 다중 인스턴스가 생성되는 대신 한 개의
주 인스턴스만 유지되도록 만들 수 있습니다. 이때 중복 생성된 인스턴스는 주 인스턴스에
신호를 보내고 종료됩니다.
`callback`은 주 인스턴스가 생성된 이후 또 다른 인스턴스가 생성됐을 때
`callback(argv, workingDirectory)` 형식으로 호출됩니다. `argv`는 두 번째 인스턴스의
명령줄 인수이며 `workingDirectory`는 현재 작업중인 디렉터리입니다. 보통 대부분의
플리케이션은 이러한 콜백이 호출될 때 주 윈도우를 포커스하고 최소화되어있으면 창
플리케이션은 이러한 콜백이 호출될 때 주 윈도우를 포커스하고 최소화되어있으면 창
복구를 실행합니다.
`callback``app``ready` 이벤트가 발생한 후 실행됨을 보장합니다.
이 메서드는 현재 실행된 플리케이션이 주 인스턴스인 경우 `false`를 반환하고
플리케이션의 로드가 계속 진행 되도록 합니다. 그리고 두 번째 중복된 인스턴스 생성인
이 메서드는 현재 실행된 플리케이션이 주 인스턴스인 경우 `false`를 반환하고
플리케이션의 로드가 계속 진행 되도록 합니다. 그리고 두 번째 중복된 인스턴스 생성인
경우 `true`를 반환합니다. (다른 인스턴스에 인수가 전달됬을 때) 이 불리언 값을 통해
중복 생성된 인스턴스는 즉시 종료시켜야 합니다.
OS X에선 사용자가 Finder에서 어플리케이션의 두 번째 인스턴스를 열려고 했을 때 자동으로
macOS에선 사용자가 Finder에서 애플리케이션의 두 번째 인스턴스를 열려고 했을 때 자동으로
**Single Instance** 화 하고 `open-file``open-url` 이벤트를 발생시킵니다. 그러나
사용자가 플리케이션을 CLI 터미널에서 실행하면 운영체제 시스템의 싱글 인스턴스
메커니즘이 무시되며 그대로 중복 실행됩니다. 따라서 OS X에서도 이 메서드를 통해 확실히
사용자가 플리케이션을 CLI 터미널에서 실행하면 운영체제 시스템의 싱글 인스턴스
메커니즘이 무시되며 그대로 중복 실행됩니다. 따라서 macOS에서도 이 메서드를 통해 확실히
중복 실행을 방지하는 것이 좋습니다.
다음 예시는 두 번째 인스턴스가 생성되었을 때 중복된 인스턴스를 종료하고 주 플리케이션
다음 예시는 두 번째 인스턴스가 생성되었을 때 중복된 인스턴스를 종료하고 주 플리케이션
인스턴스의 윈도우를 활성화 시키는 예시입니다:
```javascript
let myWindow = null;
const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
// 어플리케이션을 중복 실행했습니다. 주 어플리케이션 인스턴스를 활성화 합니다.
// 애플리케이션을 중복 실행했습니다. 주 애플리케이션 인스턴스를 활성화 합니다.
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore();
myWindow.focus();
@ -527,9 +537,9 @@ app.on('ready', () => {
### `app.releaseSingleInstance()`
모든 `makeSingleInstance`에 의해 생성된 제한을 해제합니다. 이 메서드는 다시 여러
인스턴스의 플리케이션이 나란히 실행될 수 있도록 합니다.
인스턴스의 플리케이션이 나란히 실행될 수 있도록 합니다.
### `app.setUserActivity(type, userInfo[, webpageURL])` _OS X_
### `app.setUserActivity(type, userInfo[, webpageURL])` _macOS_
* `type` String - 고유하게 activity를 식별합니다.
[`NSUserActivity.activityType`][activity-type]을 맵핑합니다.
@ -540,7 +550,7 @@ app.on('ready', () => {
`NSUserActivity`를 만들고 현재 activity에 설정합니다. 이 activity는 이후 다른 기기와
[Handoff][handoff]할 때 자격으로 사용됩니다.
### `app.getCurrentActivityType()` _OS X_
### `app.getCurrentActivityType()` _macOS_
현재 작동중인 activity의 타입을 반환합니다.
@ -548,7 +558,7 @@ app.on('ready', () => {
* `id` String
[플리케이션의 사용자 모델 ID][app-user-model-id]를 `id`로 변경합니다.
[플리케이션의 사용자 모델 ID][app-user-model-id]를 `id`로 변경합니다.
### `app.importCertificate(options, callback)` _LINUX_
@ -563,6 +573,12 @@ pkcs12 형식으로된 인증서를 플랫폼 인증서 저장소로 가져옵
다른 값은 모두 Chrominum의 [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)에
따라 실패를 의미합니다.
### `app.disableHardwareAcceleration()`
현재 애플리케이션의 하드웨어 가속을 비활성화합니다.
이 메서드는 `app``ready` 이벤트가 발생하기 전에만 호출할 수 있습니다.
### `app.commandLine.appendSwitch(switch[, value])`
Chrominum의 명령줄에 스위치를 추가합니다. `value`는 추가적인 값을 뜻하며 옵션입니다.
@ -576,56 +592,56 @@ Chrominum의 명령줄에 인수를 추가합니다. 인수는 올바르게 인
**참고:** 이 메서드는 `process.argv`에 영향을 주지 않습니다.
### `app.dock.bounce([type])` _OS X_
### `app.dock.bounce([type])` _macOS_
* `type` String (optional) - `critical` 또는 `informational`을 지정할 수 있습니다.
기본값은 `informational` 입니다.
`critical`이 전달되면 dock 아이콘이 플리케이션이 활성화되거나 요청이 중지되기 전까지
`critical`이 전달되면 dock 아이콘이 플리케이션이 활성화되거나 요청이 중지되기 전까지
통통 튀는 바운스 효과를 적용합니다.
`informational`이 전달되면 dock 아이콘이 1초만 통통 튑니다. 하지만 플리케이션이
`informational`이 전달되면 dock 아이콘이 1초만 통통 튑니다. 하지만 플리케이션이
활성화되거나 요청이 중지되기 전까지 요청은 계속 활성화로 유지 됩니다.
또한 요청을 취소할 때 사용할 수 있는 ID를 반환합니다.
### `app.dock.cancelBounce(id)` _OS X_
### `app.dock.cancelBounce(id)` _macOS_
* `id` Integer
`app.dock.bounce([type])` 메서드에서 반환한 `id`의 바운스 효과를 취소합니다.
### `app.dock.downloadFinished(filePath)` _OS X_
### `app.dock.downloadFinished(filePath)` _macOS_
* `filePath` String
`filePath`가 다운로드 폴더에 들어있다면 다운로드 스택을 바운스합니다.
### `app.dock.setBadge(text)` _OS X_
### `app.dock.setBadge(text)` _macOS_
* `text` String
dock의 badge에 표시할 문자열을 설정합니다.
### `app.dock.getBadge()` _OS X_
### `app.dock.getBadge()` _macOS_
dock의 badge에 설정된 문자열을 반환합니다.
### `app.dock.hide()` _OS X_
### `app.dock.hide()` _macOS_
dock 아이콘을 숨깁니다.
### `app.dock.show()` _OS X_
### `app.dock.show()` _macOS_
dock 아이콘을 표시합니다.
### `app.dock.setMenu(menu)` _OS X_
### `app.dock.setMenu(menu)` _macOS_
* `menu` [Menu](menu.md)
플리케이션의 [dock menu][dock-menu]를 설정합니다.
플리케이션의 [dock menu][dock-menu]를 설정합니다.
### `app.dock.setIcon(image)` _OS X_
### `app.dock.setIcon(image)` _macOS_
* `image` [NativeImage](native-image.md)

View file

@ -1,17 +1,17 @@
# autoUpdater
> 플리케이션이 자동으로 업데이트를 진행할 수 있도록 기능을 활성화합니다.
> 플리케이션이 자동으로 업데이트를 진행할 수 있도록 기능을 활성화합니다.
`autoUpdater` 모듈은 [Squirrel](https://github.com/Squirrel) 프레임워크에 대한
인터페이스를 제공합니다.
다음 프로젝트 중 하나를 선택하여, 플리케이션을 배포하기 위한 멀티-플랫폼 릴리즈
다음 프로젝트 중 하나를 선택하여, 플리케이션을 배포하기 위한 멀티-플랫폼 릴리즈
서버를 손쉽게 구축할 수 있습니다:
- [nuts][nuts]: *플리케이션을 위한 똑똑한 릴리즈 서버이며 GitHub를 백엔드로
- [nuts][nuts]: *플리케이션을 위한 똑똑한 릴리즈 서버이며 GitHub를 백엔드로
사용합니다. Squirrel을 통해 자동 업데이트를 지원합니다. (Mac & Windows)*
- [electron-release-server][electron-release-server]: *완벽하게 모든 기능을
지원하는 electron 어플리케이션을 위한 자가 호스트 릴리즈 서버입니다. auto-updater와
지원하는 electron 애플리케이션을 위한 자가 호스트 릴리즈 서버입니다. autoUpdater와
호환됩니다*
- [squirrel-updates-server][squirrel-updates-server]: *GitHub 릴리즈를 사용하는
Squirrel.Mac 와 Squirrel.Windows를 위한 간단한 node.js 기반 서버입니다*
@ -21,39 +21,41 @@ Squirrel.Mac 와 Squirrel.Windows를 위한 간단한 node.js 기반 서버입
`autoUpdater`는 기본적으로 모든 플랫폼에 대해 같은 API를 제공하지만, 여전히 플랫폼별로
약간씩 다른 점이 있습니다.
### OS X
### macOS
OS X에선 `auto-updater` 모듈이 [Squirrel.Mac][squirrel-mac]를 기반으로 작동합니다.
macOS에선 `autoUpdater` [Squirrel.Mac][squirrel-mac]를 기반으로 작동합니다.
따라서 이 모듈을 작동시키기 위해 특별히 준비해야 할 작업은 없습니다.
서버 사이드 요구 사항은 [서버 지원][server-support]을 참고하세요.
**참고:** Mac OS X에서 자동 업데이트를 지원하려면 반드시 사인이 되어있어야 합니다.
**참고:** macOS에서 자동 업데이트를 지원하려면 반드시 사인이 되어있어야 합니다.
이것은 `Squirrel.Mac`의 요구 사항입니다.
### Windows
Windows에선 `auto-updater` 모듈을 사용하기 전에 어플리케이션을 사용자의 장치에
설치해야 합니다. [grunt-electron-installer][installer]를 사용하여 어플리케이션
인스톨러를 만드는 것을 권장합니다.
Windows에선 `autoUpdater`를 사용하기 전에 애플리케이션을 사용자의 장치에
설치해야 합니다. [electron-winstaller][installer-lib],
[electron-builder][electron-builder-lib] 또는
[grunt-electron-installer][installer]를 사용하여 애플리케이션 인스톨러를 만드는 것을
권장합니다.
Windows에선 `autoUpdater` 모듈을 사용하기 전에 사용자의 장치에 어플리케이션을
Windows에선 `autoUpdater` 모듈을 사용하기 전에 사용자의 장치에 플리케이션을
설치해야 합니다. 따라서 [electron-winstaller][installer-lib] 모듈이나
[grunt-electron-installer][installer] 패키지를 사용하여 플리케이션 인스톨러를
[grunt-electron-installer][installer] 패키지를 사용하여 플리케이션 인스톨러를
만드는 것을 권장합니다.
Squirrel로 생성된 인스톨러는 [Application User Model ID][app-user-model-id]와 함께
`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`으로 형식화된 바로가기 아이콘을
생성합니다. `com.squirrel.slack.Slack``com.squirrel.code.Code`가 그 예시입니다.
`app.setAppUserModelId` API를 통해 플리케이션 ID를 동일하게 유지해야 합니다. 그렇지
않으면 Windows 작업 표시줄에 플리케이션을 고정할 때 제대로 적용되지 않을 수 있습니다.
`app.setAppUserModelId` API를 통해 플리케이션 ID를 동일하게 유지해야 합니다. 그렇지
않으면 Windows 작업 표시줄에 플리케이션을 고정할 때 제대로 적용되지 않을 수 있습니다.
서버 사이드 요구 사항 또한 OS X와 다르게 적용됩니다. 자세한 내용은
서버 사이드 요구 사항 또한 macOS와 다르게 적용됩니다. 자세한 내용은
[Squirrel.Windows][squirrel-windows]를 참고하세요.
### Linux
Linux는 따로 `auto-updater`를 지원하지 않습니다.
각 배포판의 패키지 관리자를 통해 플리케이션 업데이트를 제공하는 것을 권장합니다.
Linux는 따로 `autoUpdater`를 지원하지 않습니다.
각 배포판의 패키지 관리자를 통해 플리케이션 업데이트를 제공하는 것을 권장합니다.
## Events
@ -95,11 +97,12 @@ Returns:
`autoUpdater` 객체에서 사용할 수 있는 메서드입니다:
### `autoUpdater.setFeedURL(url)`
### `autoUpdater.setFeedURL(url[, requestHeaders])`
* `url` String
* `requestHeaders` Object _macOS_ - HTTP 요청 헤더.
`url`을 설정하고 자동 업데이터를 초기화합니다. `url`은 한번 설정되면 변경할 수 없습니다.
`url`을 설정하고 자동 업데이터를 초기화합니다.
### `autoUpdater.checkForUpdates()`
@ -108,7 +111,7 @@ Returns:
### `autoUpdater.quitAndInstall()`
플리케이션을 다시 시작하고 다운로드된 업데이트를 설치합니다.
플리케이션을 다시 시작하고 다운로드된 업데이트를 설치합니다.
이 메서드는 `update-downloaded` 이벤트가 발생한 이후에만 사용할 수 있습니다.
[squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac
@ -116,6 +119,7 @@ Returns:
[squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows
[installer]: https://github.com/electron/grunt-electron-installer
[installer-lib]: https://github.com/electron/windows-installer
[electron-builder-lib]: https://github.com/electron-userland/electron-builder
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
[electron-release-server]: https://github.com/ArekSredzki/electron-release-server
[squirrel-updates-server]: https://github.com/Aluxian/squirrel-updates-server

View file

@ -6,22 +6,61 @@
```javascript
// 메인 프로세스에서
const {BrowserWindow} = require('electron');
const {BrowserWindow} = require('electron')
// 또는 렌더러 프로세스에서
const {BrowserWindow} = require('electron').remote;
const {BrowserWindow} = require('electron').remote
let win = new BrowserWindow({width: 800, height: 600, show: false});
let win = new BrowserWindow({width: 800, height: 600})
win.on('closed', () => {
win = null;
});
})
win.loadURL('https://github.com');
win.show();
```
또한 [Frameless Window](frameless-window.md) API를 사용하여 창 테두리가 없는 윈도우
창을 생성할 수 있습니다.
## Frameless 윈도우
Frameless 윈도우를 만들거나 일정한 모양의 투명한 윈도우를 만드려면,
[Frameless 윈도우](frameless-window.md) API를 사용할 수 있습니다.
## 우아하게 윈도우 표시하기
윈도우에서 페이지를 로딩할 때, 사용자는 페이지가 로드되는 모습을 볼 것입니다.
네이티브 어플리케이션으로써 좋지 않은 경험입니다. 윈도우가 시각적인 깜빡임 없이
표시되도록 만드려면, 서로 다른 상황을 위해 두 가지 방법이 있습니다.
### `ready-to-show` 이벤트 사용하기
페이지가 로딩되는 동안, `ready-to-show` 이벤트가 랜더러 프로세스가 랜더링이 완료되었을
때 처음으로 발생합니다. 이 이벤트 이후로 윈도우를 표시하면 시각적인 깜빡임 없이 표시할
수 있습니다.
```javascript
let win = new BrowserWindow({show: false})
win.once('ready-to-show', () => {
win.show()
})
```
이 이벤트는 보통 `did-finish-load` 이벤트 이후에 발생하지만, 페이지가 너무 많은 외부
리소스를 가지고 있다면, `did-finish-load` 이벤트가 발생하기 이전에 발생할 수도
있습니다.
### `backgroundColor` 설정하기
복잡한 어플리케이션에선, `ready-to-show` 이벤트가 너무 늦게 발생할 수 있습니다.
이는 사용자가 어플리케이션이 느리다고 생각할 수 있습니다. 이러한 경우 어플리케이션
윈도우를 바로 보이도록 하고 어플리케이션의 배경과 가까운 배경색을 `backgroundColor`
통해 설정합니다:
```javascript
let win = new BrowserWindow({backgroundColor: '#2e2c29'})
win.loadURL('https://github.com')
```
참고로 `ready-to-show` 이벤트를 사용하더라도 어플리케이션을 네이티브 느낌이 나도록
하기 위해 `backgroundColor`도 같이 설정하는 것을 권장합니다.
## Class: BrowserWindow
@ -58,15 +97,20 @@ win.show();
않습니다. 기본값은 `true` 입니다.
* `closable` Boolean - 윈도우를 닫을 수 있는지 여부. Linux에선 구현되어있지 않습니다.
기본값은 `true` 입니다.
* `focusable` Boolean - 윈도우가 포커스될 수 있는지 여부입니다. 기본값은
`true`입니다. Windows에선 `focusable: false`를 설정함으로써 암시적으로
`skipTaskbar: true`도 설정됩니다. Linux에선 `focusable: false`를 설정함으로써
윈도우가 wm과 함께 반응을 중지하며 모든 작업 영역에서 윈도우가 언제나 최상단에 있게
됩니다.
* `alwaysOnTop` Boolean - 윈도우이 언제나 다른 창들 위에 유지되는지 여부.
기본값은 `false`입니다.
* `fullscreen` Boolean - 윈도우의 전체화면 활성화 여부. 이 속성을 명시적으로
`false`로 지정했을 경우, OS X에선 전체화면 버튼이 숨겨지거나 비활성됩니다. 기본값은
`false`로 지정했을 경우, macOS에선 전체화면 버튼이 숨겨지거나 비활성됩니다. 기본값은
`false` 입니다.
* `fullscreenable` Boolean - 윈도우가 전체화면 모드로 전환될 수 있는지 여부입니다.
또한 OS X에선, 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 실행할지 여부도
또한 macOS에선, 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 실행할지 여부도
포함됩니다. 기본값은 `true`입니다.
* `skipTaskbar` Boolean - 작업표시줄 플리케이션 아이콘 표시 스킵 여부. 기본값은
* `skipTaskbar` Boolean - 작업표시줄 플리케이션 아이콘 표시 스킵 여부. 기본값은
`false`입니다.
* `kiosk` Boolean - Kiosk(키오스크) 모드. 기본값은 `false`입니다.
* `title` String - 기본 윈도우 제목. 기본값은 `"Electron"`입니다.
@ -85,23 +129,23 @@ On Windows it is
활성화 되는 동시에 단일 mouse-down 이벤트를 발생시킬지 여부. 기본값은 `false`입니다.
* `disableAutoHideCursor` Boolean - 타이핑중 자동으로 커서를 숨길지 여부. 기본값은
`false`입니다.
* `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 플리케이션 메뉴바를 숨길지
* `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 플리케이션 메뉴바를 숨길지
여부. 기본값은 `false`입니다.
* `enableLargerThanScreen` Boolean - 윈도우 크기가 화면 크기보다 크게 재조정 될
수 있는지 여부. 기본값은 `false`입니다.
* `backgroundColor` String - `#66CD00``#FFF`, `#80FFFFFF` (알파 지원됨) 같이
16진수로 표현된 윈도우의 배경 색. 기본값은 `#FFF` (white).
* `hasShadow` Boolean - 윈도우가 그림자를 가질지 여부를 지정합니다. 이 속성은
OS X에서만 구현되어 있습니다. 기본값은 `true`입니다.
macOS에서만 구현되어 있습니다. 기본값은 `true`입니다.
* `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다.
몇몇 GTK+3 데스크톱 환경에서만 작동합니다. 기본값은 `false`입니다.
* `transparent` Boolean - 윈도우를 [투명화](frameless-window.md)합니다. 기본값은
`false`입니다.
* `type` String - 특정 플랫폼에만 적용되는 윈도우의 종류를 지정합니다. 기본값은
일반 윈도우 입니다. 사용할 수 있는 창의 종류는 아래를 참고하세요.
* `standardWindow` Boolean - OS X의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다.
* `standardWindow` Boolean - macOS의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다.
기본 값은 `true`입니다.
* `titleBarStyle` String, OS X - 윈도우 타이틀 바 스타일을 지정합니다. 자세한 사항은
* `titleBarStyle` String, macOS - 윈도우 타이틀 바 스타일을 지정합니다. 자세한 사항은
아래를 참고하세요.
* `webPreferences` Object - 웹 페이지 기능을 설정합니다. 사용할 수 있는 속성은
아래를 참고하세요.
@ -114,14 +158,14 @@ On Windows it is
* Linux의 경우, `desktop`, `dock`, `toolbar`, `splash`, `notification` 종류를
사용할 수 있습니다.
* OS X의 경우, `desktop`, `textured` 종류를 사용할 수 있습니다.
* macOS의 경우, `desktop`, `textured` 종류를 사용할 수 있습니다.
* `textured`는 창에 메탈 그라디언트 외관(`NSTexturedBackgroundWindowMask`)을
설정합니다.
* `desktop`은 데스크탑 배경 레벨(`kCGDesktopWindowLevel - 1`)에 윈도우를
배치합니다. 참고로 이렇게 만들어진 윈도우는 포커스, 키보드, 마우스 이벤트를 받을
수 없습니다. 하지만 편법으로 `globalShortcut`을 통해 키 입력을 받을 수 있습니다.
`titleBarStyle` 속성은 OS X 10.10 Yosemite 이후 버전만 지원하며, 다음 3가지 종류의
`titleBarStyle` 속성은 macOS 10.10 Yosemite 이후 버전만 지원하며, 다음 3가지 종류의
값을 사용할 수 있습니다:
* `default` 또는 미지정: 표준 Mac 회색 불투명 스타일을 사용합니다.
@ -148,7 +192,7 @@ On Windows it is
페이지에서 같은 `partition`을 사용할 수 있습니다. 만약 `persist:` 접두어로
시작하지 않으면 페이지는 인-메모리 세션을 사용합니다. 여러 페이지에서 같은
`partition`을 지정하면 같은 세션을 공유할 수 있습니다. `partition`을 지정하지
않으면 플리케이션의 기본 세션이 사용됩니다.
않으면 플리케이션의 기본 세션이 사용됩니다.
* `zoomFactor` Number - 페이지의 기본 줌 값을 지정합니다. 예를 들어 `300%`
표현하려면 `3.0`으로 지정합니다. 기본값은 `1.0`입니다.
* `javascript` Boolean - 자바스크립트를 활성화합니다. 기본값은 `false`입니다.
@ -174,11 +218,14 @@ On Windows it is
활성화합니다. 기본값은 `false`입니다.
* `directWrite` Boolean - Windows에서 폰트 렌더링을 위해 DirectWrite를
사용하는지를 지정합니다. 기본값은 `true`입니다.
* `scrollBounce` Boolean - OS X에서 스크롤 튕기기 효과 (탄성 밴딩)를 활성화 합니다.
* `scrollBounce` Boolean - macOS에서 스크롤 튕기기 효과 (탄성 밴딩)를 활성화 합니다.
기본값은 `false`입니다.
* `blinkFeatures` String - `CSSVariables,KeyboardEventKey`같은 `,`로 구분된
기능 문자열들의 리스트입니다. 지원하는 전체 기능 문자열들은
[setFeatureEnabledFromString][blink-feature-string] 함수에서 찾을 수 있습니다.
* `blinkFeatures` String - 활성화 할 `CSSVariables,KeyboardEventKey`같이 `,`
구분된 기능 문자열들의 리스트입니다. [RuntimeEnabledFeatures.in][blink-feature-string]
파일에서 찾을 수 있습니다.
* `disableBlinkFeatures` String - 비활성화 할 `CSSVariables,KeyboardEventKey`같이
`,`로 구분된 기능 문자열들의 리스트입니다. [RuntimeEnabledFeatures.in][blink-feature-string]
파일에서 찾을 수 있습니다.
* `defaultFontFamily` Object - font-family의 기본 폰트를 지정합니다.
* `standard` String - 기본값 `Times New Roman`.
* `serif` String - 기본값 `Times New Roman`.
@ -227,7 +274,7 @@ window.onbeforeunload = (e) => {
// 일반적인 브라우저와는 달리 사용자에게 확인 창을 보여주지 않고, non-void 값을 반환하면
// 조용히 닫기를 취소합니다.
// Dialog API를 통해 사용자가 플리케이션을 종료할지 정할 수 있도록 확인 창을 표시하는 것을
// Dialog API를 통해 사용자가 플리케이션을 종료할지 정할 수 있도록 확인 창을 표시하는 것을
// 추천합니다.
e.returnValue = false;
};
@ -262,6 +309,11 @@ window.onbeforeunload = (e) => {
윈도우가 숨겨진 상태일 때 발생하는 이벤트입니다.
### Event: 'ready-to-show'
웹 페이지가 완전히 랜더링되어 윈도우가 시각적인 깜빡임없이 컨텐츠를 보여줄 수 있을 때
발생하는 이벤트입니다.
### Event: 'maximize'
윈도우가 최대화됐을 때 발생하는 이벤트입니다.
@ -286,9 +338,9 @@ window.onbeforeunload = (e) => {
윈도우가 새로운 위치로 이동될 때 발생하는 이벤트입니다.
__참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias)으로 사용됩니다.
__참고__: macOS에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias)으로 사용됩니다.
### Event: 'moved' _OS X_
### Event: 'moved' _macOS_
윈도우가 새로운 위치로 이동되었을 때 발생하는 이벤트입니다. (한 번만)
@ -333,15 +385,15 @@ someWindow.on('app-command', (e, cmd) => {
});
```
### Event: 'scroll-touch-begin' _OS X_
### Event: 'scroll-touch-begin' _macOS_
스크롤 휠 이벤트가 동작하기 시작했을 때 발생하는 이벤트입니다.
### Event: 'scroll-touch-end' _OS X_
### Event: 'scroll-touch-end' _macOS_
스크롤 휠 이벤트가 동작을 멈췄을 때 발생하는 이벤트입니다.
### Event: 'swipe' _OS X_
### Event: 'swipe' _macOS_
Returns:
@ -361,7 +413,7 @@ Returns:
### `BrowserWindow.getFocusedWindow()`
플리케이션에서 포커스된 윈도우를 반환합니다. 포커스된 윈도우가 없을 경우 `null`
플리케이션에서 포커스된 윈도우를 반환합니다. 포커스된 윈도우가 없을 경우 `null`
반환합니다.
### `BrowserWindow.fromWebContents(webContents)`
@ -382,8 +434,11 @@ ID에 해당하는 윈도우를 찾습니다.
`path`에 있는 개발자 도구 확장 기능을 추가합니다. 그리고 확장 기능의 이름을 반환합니다.
확장 기능은 기억됩니다. 따라서 API는 단 한 번만 호출되어야 합니다.
이 API는 실제 프로그램 작성에 사용할 수 없습니다.
확장 기능은 기억됩니다. 따라서 API는 단 한 번만 호출되어야 합니다. 이 API는 실제
프로그램 작성에 사용할 수 없습니다. 만약 이미 로드된 확장 기능을 추가하려 한다면, 이
메서드는 아무것도 반환하지 않고 콘솔에 경고가 로그됩니다.
**참고:** 이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전까지 사용할 수 없습니다.
### `BrowserWindow.removeDevToolsExtension(name)`
@ -391,6 +446,21 @@ ID에 해당하는 윈도우를 찾습니다.
`name`에 해당하는 개발자 도구 확장 기능을 제거합니다.
**참고:** 이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전까지 사용할 수 없습니다.
### `BrowserWindow.getDevToolsExtensions()`
키는 확장 기능 이름을 값은 `name``version` 속성을 포함하는 객체를 가지는 객체를
반환합니다.
개발자 도구 확장 기능이 설치되었는지 확인하려면 다음과 같이 실행할 수 있습니다:
```javascript
let installed = BrowserWindow.getDevToolsExtensions().hasOwnProperty('devtron')
```
**참고:** 이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전까지 사용할 수 없습니다.
## Instance Properties
`new BrowserWindow`로 생성한 객체는 다음과 같은 속성을 가지고 있습니다:
@ -492,7 +562,7 @@ let win = new BrowserWindow({width: 800, height: 600});
윈도우가 전체화면 모드 상태인지 여부를 반환합니다.
### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_
### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_
* `aspectRatio` 유지하려 하는 콘텐츠 뷰 일부의 종횡비
* `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기.
@ -520,7 +590,7 @@ let win = new BrowserWindow({width: 800, height: 600});
* `width` Integer
* `height` Integer
* `animate` Boolean (optional) _OS X_
* `animate` Boolean (optional) _macOS_
윈도우를 지정한 `width`, `height`, `x`, `y`로 크기 재조정 및 이동합니다.
@ -532,7 +602,7 @@ let win = new BrowserWindow({width: 800, height: 600});
* `width` Integer
* `height` Integer
* `animate` Boolean (optional) _OS X_
* `animate` Boolean (optional) _macOS_
`width``height` 값으로 윈도우 크기를 재조정합니다. (너비, 높이)
@ -544,7 +614,7 @@ let win = new BrowserWindow({width: 800, height: 600});
* `width` Integer
* `height` Integer
* `animate` Boolean (optional) _OS X_
* `animate` Boolean (optional) _macOS_
윈도우 클라이언트 영역(웹 페이지)의 크기를 `width`, `height`로 재조정합니다.
@ -584,38 +654,38 @@ let win = new BrowserWindow({width: 800, height: 600});
사용자에 의해 윈도우의 크기가 재조정될 수 있는지 여부를 반환합니다.
### `win.setMovable(movable)` _OS X_ _Windows_
### `win.setMovable(movable)` _macOS_ _Windows_
* `movable` Boolean
사용자에 의해 윈도우를 이동시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도
일어나지 않습니다.
### `win.isMovable()` _OS X_ _Windows_
### `win.isMovable()` _macOS_ _Windows_
사용자에 의해 윈도우를 이동시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`
반환합니다.
### `win.setMinimizable(minimizable)` _OS X_ _Windows_
### `win.setMinimizable(minimizable)` _macOS_ _Windows_
* `minimizable` Boolean
사용자에 의해 윈도우를 최소화시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도
일어나지 않습니다.
### `win.isMinimizable()` _OS X_ _Windows_
### `win.isMinimizable()` _macOS_ _Windows_
사용자에 의해 윈도우를 최소화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`
반환합니다.
### `win.setMaximizable(maximizable)` _OS X_ _Windows_
### `win.setMaximizable(maximizable)` _macOS_ _Windows_
* `maximizable` Boolean
사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도
일어나지 않습니다.
### `win.isMaximizable()` _OS X_ _Windows_
### `win.isMaximizable()` _macOS_ _Windows_
사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`
반환합니다.
@ -632,14 +702,14 @@ let win = new BrowserWindow({width: 800, height: 600});
최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를
반환합니다.
### `win.setClosable(closable)` _OS X_ _Windows_
### `win.setClosable(closable)` _macOS_ _Windows_
* `closable` Boolean
사용자에 의해 윈도우가 수동적으로 닫힐 수 있는지 여부를 지정합니다. Linux에선 아무 일도
일어나지 않습니다.
### `win.isClosable()` _OS X_ _Windows_
### `win.isClosable()` _macOS_ _Windows_
사용자에 의해 윈도우가 수동적으로 닫힐 수 있는지 여부를 반환합니다. Linux에선 항상
`true`를 반환합니다.
@ -663,7 +733,7 @@ let win = new BrowserWindow({width: 800, height: 600});
* `x` Integer
* `y` Integer
* `animate` Boolean (optional) _OS X_
* `animate` Boolean (optional) _macOS_
윈도우의 위치를 `x`, `y`로 이동합니다.
@ -683,9 +753,9 @@ let win = new BrowserWindow({width: 800, height: 600});
**참고:** 웹 페이지의 제목과 네이티브 윈도우의 제목은 서로 다를 수 있습니다.
### `win.setSheetOffset(offsetY[, offsetX])` _OS X_
### `win.setSheetOffset(offsetY[, offsetX])` _macOS_
Mac OS X에서 시트를 부착할 위치를 지정합니다. 기본적으로 시트는 윈도우의 프레임 바로
macOS에서 시트를 부착할 위치를 지정합니다. 기본적으로 시트는 윈도우의 프레임 바로
아래의 위치에 부착됩니다. 아마도 이 기능은 보통 다음과 같이 HTML 렌더링된 툴바 밑에
표시하기 위해 사용할 것입니다:
@ -704,7 +774,7 @@ win.setSheetOffset(toolbarRect.height);
* `skip` Boolean
플리케이션 아이콘을 작업표시줄에 보이지 않도록 설정합니다.
플리케이션 아이콘을 작업표시줄에 보이지 않도록 설정합니다.
### `win.setKiosk(flag)`
@ -720,7 +790,7 @@ Kiosk(키오스크) 모드를 설정합니다.
`Buffer` 상의 플랫폼에 따른 윈도우 핸들을 반환합니다.
핸들의 타입에 따라 적절히 캐스팅됩니다. Windows의 `HWND`, OS X`NSView*`, Linux의
핸들의 타입에 따라 적절히 캐스팅됩니다. Windows의 `HWND`, macOS의 `NSView*`, Linux의
`Window` (`unsigned long`)를 예로 들 수 있습니다.
### `win.hookWindowMessage(message, callback)` _Windows_
@ -747,24 +817,24 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지
모든 메시지 훅을 등록 해제합니다.
### `win.setRepresentedFilename(filename)` _OS X_
### `win.setRepresentedFilename(filename)` _macOS_
* `filename` String
윈도우 대표 파일의 경로명을 설정합니다. 파일의 아이콘이 윈도우 타이틀 바에 표시됩니다.
### `win.getRepresentedFilename()` _OS X_
### `win.getRepresentedFilename()` _macOS_
윈도우 대표 파일의 경로명을 반환합니다.
### `win.setDocumentEdited(edited)` _OS X_
### `win.setDocumentEdited(edited)` _macOS_
* `edited` Boolean
윈도우의 문서가 변경되었는지 여부를 설정합니다. 그리고 `true`로 설정했을 때 타이틀 바의
아이콘이 회색으로 표시됩니다.
### `win.isDocumentEdited()` _OS X_
### `win.isDocumentEdited()` _macOS_
윈도우의 문서가 변경되었는지 여부를 반환합니다.
@ -803,7 +873,7 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지
* `progress` Double
작업표시줄에 표시되고 있는 플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0]
작업표시줄에 표시되고 있는 플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0]
사이의 값을 지정할 수 있습니다.
진행 상태가 < 0 되면 진행 상태 표시를 제거합니다.
@ -820,16 +890,16 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고
* `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다
현재 작업표시줄 아이콘에 16 x 16 픽셀 크기의 오버레이를 지정합니다. 보통 이 기능은
플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다.
플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다.
### `win.setHasShadow(hasShadow)` _OS X_
### `win.setHasShadow(hasShadow)` _macOS_
* `hasShadow` (Boolean)
윈도우가 그림자를 가질지 여부를 지정합니다. Windows와 Linux에선 아무 일도 일어나지
않습니다.
### `win.hasShadow()` _OS X_
### `win.hasShadow()` _macOS_
윈도우가 그림자를 가지고 있는지 여부를 반환합니다. Windows와 Linux에선 항상 `true`
반환합니다.
@ -864,9 +934,9 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고
눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해
만들어졌습니다.
### `win.showDefinitionForSelection()` _OS X_
### `win.showDefinitionForSelection()` _macOS_
페이지의 선택된 단어에 대한 사전 검색 결과 팝업을 표시합니다.
`webContents.showDefinitionForSelection()`와 같습니다.
### `win.setIcon(icon)` _Windows_ _Linux_
@ -895,7 +965,7 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고
메뉴 막대의 표시 여부를 설정합니다. 만약 메뉴 막대 자동 숨김 상태라면 여전히 사용자가
`Alt` 키를 입력하여 메뉴 막대를 표시되도록 할 수 있습니다.
**역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`를 호출해야 합니다.
**역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`를 호출해야 합니다.
단순히 이 API를 사용하면 여전히 메뉴에 등록된 핫 키가 작동합니다.
### `win.isMenuBarVisible()`
@ -916,10 +986,19 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고
**참고:** 이 API는 Windows에서 언제나 false를 반환합니다.
### `win.setIgnoreMouseEvents(ignore)` _OS X_
### `win.setIgnoreMouseEvents(ignore)`
* `ignore` Boolean
윈도우에서 일어나는 모든 마우스 이벤트를 무시합니다.
윈도우가 모든 마우스 이벤트를 무시하게 만듭니다.
[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=576
이 윈도우에서 일어나는 모든 마우스 이벤트가 이 윈도우 밑의 윈도우로 전달됩니다. 하지만
이 윈도우가 포커스되어 있다면, 여전히 키보드 이벤트는 받을 수 있습니다.
### `win.setFocusable(focusable)` _Windows_
* `focusable` Boolean
윈도우가 포커스될 수 있는지 여부를 변경합니다.
[blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in

View file

@ -2,8 +2,8 @@
> Electron에서 지원하는 커맨드 명령줄 스위치입니다.
플리케이션 메인 스크립트의 [app][app] 모듈에서 [ready][ready] 이벤트가 실행되기
전에 [app.commandLine.appendSwitch][append-switch]를 호출하면, 플리케이션의
플리케이션 메인 스크립트의 [app][app] 모듈에서 [ready][ready] 이벤트가 실행되기
전에 [app.commandLine.appendSwitch][append-switch]를 호출하면, 플리케이션의
명령줄 옵션을 추가로 지정할 수 있습니다:
```javascript
@ -149,7 +149,7 @@ Chromium이 렌더러 프로세스의 보이지 않는 페이지의 우선순위
Chromium의 로그를 콘솔에 출력합니다.
이 스위치는 플리케이션이 로드되기 전에 분석 되므로 `app.commandLine.appendSwitch`
이 스위치는 플리케이션이 로드되기 전에 분석 되므로 `app.commandLine.appendSwitch`
메서드에선 사용할 수 없습니다. 하지만 `ELECTRON_ENABLE_LOGGING` 환경 변수를 설정하면
본 스위치를 지정한 것과 같은 효과를 낼 수 있습니다.

View file

@ -2,7 +2,7 @@
> 원격 서버에 크래시 정보를 보고합니다.
다음 예시는 윈격 서버에 플리케이션 크래시 정보를 자동으로 보고하는 예시입니다:
다음 예시는 윈격 서버에 플리케이션 크래시 정보를 자동으로 보고하는 예시입니다:
```javascript
const {crashReporter} = require('electron');
@ -39,7 +39,7 @@ crashReporter.start({
다른 crashReporter API를 사용하기 전에 이 메서드를 먼저 호출해야 합니다.
**참고:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad`
**참고:** macOS에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad`
클라이언트를 사용합니다. 오류 수집 기능을 활성화 시키려면 오류를 수집하고 싶은 메인
프로세스나 렌더러 프로세스에서 `crashReporter.start` 메서드를 호출하여 `crashpad`
초기화해야 합니다.

View file

@ -105,7 +105,7 @@ const {dialog} = require('electron').remote;
* `cancelId` Integer - 유저가 대화 상자의 버튼을 클릭하지 않고 대화 상자를 취소했을
때 반환되는 버튼의 인덱스입니다. 기본적으로 버튼 리스트가 "cancel" 또는 "no"
라벨을 가지고 있을 때 해당 버튼의 인덱스를 반환합니다. 따로 두 라벨이 지정되지
않은 경우 0을 반환합니다. OS X와 Windows에선 `cancelId` 지정 여부에 상관없이
않은 경우 0을 반환합니다. macOS와 Windows에선 `cancelId` 지정 여부에 상관없이
"Cancel" 버튼이 언제나 `cancelId`로 지정됩니다.
* `noLink` Boolean - Windows에서 Electron은 ("Cancel"이나 "Yes"와 같은) 흔히
사용되는 버튼을 찾으려고 시도하고 대화 상자 내에서 해당 버튼을 커맨드 링크처럼
@ -116,8 +116,8 @@ const {dialog} = require('electron').remote;
대화 상자를 표시합니다. `browserWindow`를 지정하면 대화 상자가 완전히 닫힐 때까지
지정한 창을 사용할 수 없습니다. 완료 시 유저가 선택한 버튼의 인덱스를 반환합니다.
**역주:** 부정을 표현하는 "아니오", "취소"와 같은 한글 단어는 지원되지 않습니다. 만약
OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로
**역주:** 부정을 표현하는 "아니오", "취소"와 같은 한글 단어는 지원되지 않습니다. 만약
macOS 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로
해당 대화 상자를 끄게 되면 "확인"을 누른 것으로 판단되어 버립니다. 이를 해결하려면
"Cancel"을 대신 사용하거나 BrowserWindow API를 사용하여 대화 상자를 직접 구현해야
합니다.
@ -130,13 +130,13 @@ OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지
에러 메시지를 보여주는 대화 상자를 표시합니다.
이 함수는 `app` 모듈의 `ready` 이벤트가 발생하기 전까지 사용할 수 있습니다. 이 메서드는
보통 플리케이션이 시작되기 전에 특정한 에러를 표시하기 위해 사용됩니다. 만약
보통 플리케이션이 시작되기 전에 특정한 에러를 표시하기 위해 사용됩니다. 만약
Linux에서 `ready` 이벤트가 발생하기 전에 이 API를 호출할 경우, 메시지는 stderr를
통해서 표시되며 GUI 대화 상자는 표시되지 않습니다.
## Sheets
Mac OS X에선, `browserWindow` 인수에 `BrowserWindow` 객체 참조를 전달하면 대화
macOS에선, `browserWindow` 인수에 `BrowserWindow` 객체 참조를 전달하면 대화
상자가 해당 윈도우에 시트처럼 표시되도록 표현할 수 있습니다. 윈도우의 객체 참조가
제공되지 않으면 모달 형태로 표시됩니다.

View file

@ -2,49 +2,70 @@
> 원격 소스로부터의 파일 다운로드를 제어합니다.
`DownloadItem`은 EventEmitter를 상속받았으며 Electron의 다운로드 아이템을 표현합니다.
이 클래스 객체는 `Session` 모듈`will-download` 이벤트에 사용되며 사용자가 다운로드
아이템을 다룰 수 있도록 도와줍니다.
`DownloadItem``EventEmitter`를 상속받았으며 Electron의 다운로드 아이템을
표현합니다. 이 클래스 객체는 `Session` 클래스`will-download` 이벤트에 사용되며
사용자가 다운로드 아이템을 다룰 수 있도록 도와줍니다.
```javascript
// 메인 프로세스
win.webContents.session.on('will-download', (event, item, webContents) => {
// Set the save path, making Electron not to prompt a save dialog.
item.setSavePath('/tmp/save.pdf');
console.log(item.getMimeType());
console.log(item.getFilename());
console.log(item.getTotalBytes());
item.on('updated', () => {
console.log('Received bytes: ' + item.getReceivedBytes());
});
item.on('done', (e, state) => {
if (state === 'completed') {
console.log('Download successfully');
} else {
console.log('Download is cancelled or interrupted that can\'t be resumed');
item.setSavePath('/tmp/save.pdf')
item.on('updated', (event, state) => {
if (state === 'interrupted') {
console.log('Download is interrupted but can be resumed')
} else if (state === 'progressing') {
if (item.isPaused()) {
console.log('Download is paused')
} else {
console.log(`Received bytes: ${item.getReceivedBytes()}`)
}
}
});
});
})
item.once('done', (event, state) => {
if (state === 'completed') {
console.log('Download successfully')
} else {
console.log(`Download failed: ${state}`)
}
})
})
```
## Events
### Event: 'updated'
`downloadItem`이 갱신될 때 발생하는 이벤트입니다.
### Event: 'done'
Returns:
* `event` Event
* `state` String
다운로드가 업데이트되었으며 아직 끝나지 않았을 때 발생하는 이벤트입니다.
`state`는 다음 중 하나가 될 수 있습니다:
* `progressing` - 다운로드가 진행중입니다.
* `interrupted` - 다운로드가 중지되었으며 다시 재개할 수 있습니다.
### Event: 'done'
Returns:
* `event` Event
* `state` String
* `completed` - 다운로드가 성공적으로 완료되었습니다.
* `cancelled` - 다운로드가 취소되었습니다.
* `interrupted` - 다운로드 중 파일 서버로부터의 연결이 끊겼습니다.
다운로드가 종료될 때 발생하는 이벤트입니다. 이 이벤트는 다운로드 중 문제가 발생하여
중단되거나, 모두 성공적으로 완료된 경우, `downloadItem.cancel()` 같은 메서드를 통해
취소하는 경우의 종료 작업이 모두 포함됩니다.
`state`는 다음 중 하나가 될 수 있습니다:
* `completed` - 다운로드가 성공적으로 완료되었습니다.
* `cancelled` - 다운로드가 취소되었습니다.
* `interrupted` - 다운로드가 중지되었으며 다시 재개할 수 있습니다.
## Methods
`downloadItem` 객체는 다음과 같은 메서드를 가지고 있습니다:
@ -61,10 +82,18 @@ win.webContents.session.on('will-download', (event, item, webContents) => {
다운로드를 일시 중지합니다.
### `downloadItem.isPaused()`
다운로드가 일시 중지되었는지 여부를 반환합니다.
### `downloadItem.resume()`
중디된 다운로드를 재개합니다.
### `downloadItem.canResume()`
다운로드를 재개할 수 있는지 여부를 반환합니다.
### `downloadItem.cancel()`
다운로드를 취소합니다.
@ -101,3 +130,14 @@ win.webContents.session.on('will-download', (event, item, webContents) => {
### `downloadItem.getContentDisposition()`
응답 헤더에서 Content-Disposition 필드를 문자열로 반환합니다.
### `downloadItem.getState()`
현재 상태를 `String` 타입으로 가져옵니다.
값은 다음이 될 수 있습니다:
* `progressing` - 다운로드가 진행중입니다.
* `completed` - 다운로드가 성공적으로 완료되었습니다.
* `cancelled` - 다운로드가 취소되었습니다.
* `interrupted` - 다운로드가 중지되었습니다.

View file

@ -1,8 +1,8 @@
# 환경 변수
> 플리케이션의 구성과 동작을 코드 변경 없이 제어합니다.
> 플리케이션의 구성과 동작을 코드 변경 없이 제어합니다.
특정 Electron 동작은 명령줄 플래그와 플리케이션의 코드보다 먼저 초기화되어야 하므로
특정 Electron 동작은 명령줄 플래그와 플리케이션의 코드보다 먼저 초기화되어야 하므로
환경 변수에 의해 작동합니다.
POSIX 쉘의 예시입니다:

View file

@ -1,40 +1,40 @@
# Frameless Window
# Frameless 윈도우
> 툴바, 테두리, 시각적인 "chrome" 없이 윈도우를 엽니다.
Frameless Window는 [창 테두리](https://developer.mozilla.org/ko/docs/Glossary/Chrome)가
Frameless 윈도우는 [창 테두리](https://developer.mozilla.org/ko/docs/Glossary/Chrome)가
없는 윈도우를 말합니다. 이 기능은 윈도우의 일부분인 툴바와 같이 웹 페이지의 일부분이
아닌 부분을 보이지 않도록 합니다. [`BrowserWindow`](browser-window.md) 클래스의
옵션에서 설정할 수 있습니다.
## Frameless Window 만들기
## Frameless 윈도우 만들기
Frameless Window를 만드려면 [BrowserWindow](browser-window.md) 객체의
Frameless 윈도우를 만드려면 [BrowserWindow](browser-window.md) 객체의
`options` 객체에서 `frame` 옵션을 `false`로 지정하면 됩니다:
```javascript
const {BrowserWindow} = require('electron');
let win = new BrowserWindow({width: 800, height: 600, frame: false});
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600, frame: false})
```
### 최신 OS X에서 사용할 수 있는 대안
### 최신 macOS에서 사용할 수 있는 대안
OS X 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 만들 때 새로운 방법을
macOS 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 만들 때 새로운 방법을
사용할 수 있습니다. `frame` 옵션을 `false`로 지정하여 제목과 창 구성 요소를 모두
비활성화하는 대신 새로운 `titleBarStyle` 옵션을 통해 제목만 숨기고 창 구성 요소
("신호등 버튼")의 기능과 창 크기를 그대로 유지할 수 있습니다:
```javascript
let win = new BrowserWindow({titleBarStyle: 'hidden'});
let win = new BrowserWindow({titleBarStyle: 'hidden'})
```
## 투명한 창 만들기
Frameless Window 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`
Frameless 윈도우 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`
바꿔주기만 하면됩니다:
```javascript
let win = new BrowserWindow({transparent: true, frame: false});
let win = new BrowserWindow({transparent: true, frame: false})
```
### API의 한계
@ -45,18 +45,28 @@ let win = new BrowserWindow({transparent: true, frame: false});
* 투명한 창은 크기를 조절할 수 없습니다. `resizable` 속성을 `true`로 할 경우 몇몇
플랫폼에선 크래시가 일어납니다.
* `blur` 필터는 웹 페이지에서만 적용됩니다. 윈도우 아래 콘텐츠에는 블러 효과를 적용할
방법이 없습니다. (예시: 유저의 시스템에 열린 다른 플리케이션)
방법이 없습니다. (예시: 유저의 시스템에 열린 다른 플리케이션)
* Windows에선 DWM(데스크톱 창 관리자)가 비활성화되어 있을 경우 투명한 창이 작동하지
않습니다.
* Linux를 사용할 경우 [alpha channel doesn't work on some NVidia drivers](https://code.google.com/p/chromium/issues/detail?id=369209)
upstream 버그가 있는 관계로 투명한 창 기능을 사용하려면 CLI 옵션에
`--enable-transparent-visuals --disable-gpu`을 추가해야 합니다. 이 옵션은 GPU의
사용을 중단하고 윈도우를 생성하는데 ARGB를 사용할 수 있도록 해줍니다.
* OS X(Mac)에선 네이티브 창에서 보여지는 그림자가 투명한 창에선 보이지 않습니다.
* macOS(Mac)에선 네이티브 창에서 보여지는 그림자가 투명한 창에선 보이지 않습니다.
## 클릭이 통과될 수 있는 윈도우
클릭이 통과될 수 있는 윈도우를 만드려면, i.e. 모든 마우스 이벤트를 무시하는 윈도우를
만드려면, [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events] API를 사용하여
구현할 수 있습니다:
```javascript
win.setIgnoreMouseEvents(true)
```
## 드래그 가능 위치 지정
기본적으로 Frameless Window는 드래그 할 수 없습니다. 어플리케이션의 CSS에서 특정
기본적으로 Frameless 윈도우는 드래그 할 수 없습니다. 애플리케이션의 CSS에서 특정
범위를 `-webkit-app-region: drag`로 지정하면 OS의 기본 타이틀 바 처럼 드래그 되도록
할 수 있습니다. 그리고 `-webkit-app-region: no-drag`를 지정해서 드래그 불가능 영역을
만들 수도 있습니다. 현재 사각형 형태의 범위만 지원합니다.
@ -83,7 +93,7 @@ button {
## 텍스트 선택
Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다. 예를
Frameless 윈도우에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다. 예를
들어 타이틀 바를 드래그 할 때 타이틀 바의 텍스트를 실수로 선택할 수 있습니다. 이를
방지하기 위해 다음과 같이 드래그 영역의 텍스트 선택 기능을 비활성화해야 할 필요가
있습니다:
@ -101,3 +111,5 @@ Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을
드래그 가능 영역에서 오른쪽 클릭 할 경우 시스템 메뉴가 팝업 됩니다. 이러한 이유로
컨텍스트 메뉴 지정 시 모든 플랫폼에서 정상적으로 작동하게 하려면 커스텀 컨텍스트 메뉴를
드래그 영역 내에 만들어선 안됩니다.
[ignore-mouse-events]: browser-window.md#winsetignoremouseeventsignore

View file

@ -1,12 +1,12 @@
# globalSortcut
> 플리케이션에 키보드 포커스가 없을 때도 키보드 이벤트를 받을 수 있도록 합니다.
> 플리케이션에 키보드 포커스가 없을 때도 키보드 이벤트를 받을 수 있도록 합니다.
`globalShortcut` 모듈은 운영체제의 전역 키보드 단축키를 등록/해제 하는 방법을
제공합니다. 이 모듈을 사용하여 사용자가 다양한 작업을 편하게 할 수 있도록 단축키를
정의 할 수 있습니다.
**참고:** 등록된 단축키는 플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할
**참고:** 등록된 단축키는 플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할
때도 계속해서 작동합니다. 이 모듈은 `app` 모듈의 `ready` 이벤트가 발생하기 전까지
사용할 수 없습니다.
@ -48,8 +48,8 @@ app.on('will-quit', () => {
`accelerator`의 전역 단축키를 등록합니다. 유저로부터 등록된 단축키가 눌렸을 경우
`callback` 함수가 호출됩니다.
accelerator가 이미 다른 플리케이션에서 사용 중일 경우, 이 작업은 조용히 실패합니다.
이러한 동작은 플리케이션이 전역 키보드 단축키를 가지고 충돌이 일어나지 않도록 하기
accelerator가 이미 다른 플리케이션에서 사용 중일 경우, 이 작업은 조용히 실패합니다.
이러한 동작은 플리케이션이 전역 키보드 단축키를 가지고 충돌이 일어나지 않도록 하기
위해 운영체제에 의해 예정된 동작입니다.
### `globalShortcut.isRegistered(accelerator)`
@ -58,8 +58,8 @@ accelerator가 이미 다른 어플리케이션에서 사용 중일 경우, 이
지정된 `accelerator` 단축키가 등록되었는지 여부를 확인합니다.
Accelerator가 이미 다른 플리케이션에서 사용 중일 경우, 여전히 `false`를 반환합니다.
이러한 동작은 플리케이션이 전역 키보드 단축키를 가지고 충돌이 일어나지 않도록 하기
Accelerator가 이미 다른 플리케이션에서 사용 중일 경우, 여전히 `false`를 반환합니다.
이러한 동작은 플리케이션이 전역 키보드 단축키를 가지고 충돌이 일어나지 않도록 하기
위해 운영체제에 의해 예정된 동작입니다.
### `globalShortcut.unregister(accelerator)`

View file

@ -1,6 +1,6 @@
# MenuItem
> 네이티브 플리케이션 메뉴와 컨텍스트 메뉴에 아이템을 추가합니다.
> 네이티브 플리케이션 메뉴와 컨텍스트 메뉴에 아이템을 추가합니다.
[`menu`](menu.md)에서 예시를 확인할 수 있습니다.
@ -46,22 +46,25 @@
* `cut`
* `copy`
* `paste`
* `pasteandmatchstyle`
* `selectall`
* `delete`
* `minimize` - 현재 윈도우를 최소화합니다
* `close` - 현재 윈도우를 닫습니다
OS X에서의 `role`은 다음 값을 추가로 가질 수 있습니다:
macOS에서의 `role`은 다음 값을 추가로 가질 수 있습니다:
* `about` - `orderFrontStandardAboutPanel` 액션에 대응
* `hide` - `hide` 액션에 대응
* `hideothers` - `hideOtherApplications` 액션에 대응
* `unhide` - `unhideAllApplications` 액션에 대응
* `front` - `arrangeInFront` 액션에 대응
* `zoom` - `performZoom` 액션에 대응
* `window` - 부 메뉴를 가지는 "Window" 메뉴
* `help` - 부 메뉴를 가지는 "Help" 메뉴
* `services` - 부 메뉴를 가지는 "Services" 메뉴
OS X에서는 `role`을 지정할 때, `label``accelerator`만 MenuItem에 효과가
macOS에서는 `role`을 지정할 때, `label``accelerator`만 MenuItem에 효과가
적용되도록 변경되며, 다른 옵션들은 모두 무시됩니다.
## Instance Properties

View file

@ -1,6 +1,6 @@
# Menu
> 네이티브 플리케이션 메뉴와 컨텍스트 메뉴를 생성합니다.
> 네이티브 플리케이션 메뉴와 컨텍스트 메뉴를 생성합니다.
이 모듈은 메인 프로세스용 모듈이지만 `remote` 모듈을 통해 렌더러 프로세스에서도 사용할
수 있습니다.
@ -30,7 +30,7 @@ window.addEventListener('contextmenu', (e) => {
```
또 하나의 예를 들자면 다음 예시는 렌더러 프로세스에서 template API를 사용하여
플리케이션 메뉴를 만듭니다:
플리케이션 메뉴를 만듭니다:
```javascript
const template = [
@ -65,6 +65,15 @@ const template = [
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Paste and Match Style',
accelerator: 'Shift+Command+V',
role: 'pasteandmatchstyle'
},
{
label: 'Delete',
role: 'delete'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
@ -173,7 +182,21 @@ if (process.platform === 'darwin') {
]
});
// Window menu.
template[3].submenu.push(
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
@ -181,7 +204,7 @@ if (process.platform === 'darwin') {
label: 'Bring All to Front',
role: 'front'
}
);
];
}
const menu = Menu.buildFromTemplate(template);
@ -202,18 +225,25 @@ Menu.setApplicationMenu(menu);
* `menu` Menu
지정한 `menu`어플리케이션 메뉴로 만듭니다. OS X에선 상단바에 표시되며 Windows와
지정한 `menu`애플리케이션 메뉴로 만듭니다. macOS에선 상단바에 표시되며 Windows와
Linux에선 각 창의 상단에 표시됩니다.
### `Menu.sendActionToFirstResponder(action)` _OS X_
**참고** 이 API는 `app``ready` 이벤트가 발생한 이후에 호출해야 합니다.
### `Menu.getApplicationMenu()`
설정되어있는 어플리케이션 메뉴를 반환합니다. (`Menu`의 인스턴스) 만약 없다면 `null`
반환합니다.
### `Menu.sendActionToFirstResponder(action)` _macOS_
* `action` String
`action`을 어플리케이션의 first responder에 전달합니다. 이 메서드는 Cocoa 메뉴
`action`플리케이션의 first responder에 전달합니다. 이 메서드는 Cocoa 메뉴
동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem``role` 속성에 사용됩니다.
OS X의 네이티브 액션에 대해 자세히 알아보려면
[OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7)
macOS의 네이티브 액션에 대해 자세히 알아보려면
[macOS Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7)
문서를 참고하세요.
### `Menu.buildFromTemplate(template)`
@ -235,13 +265,13 @@ OS X의 네이티브 액션에 대해 자세히 알아보려면
* `browserWindow` BrowserWindow (optional) - 기본값은 `null`입니다.
* `x` Number (optional) - 기본값은 -1입니다.
* `y` Number (만약 `x`를 지정한 경우 **필수 항목**) - 기본값은 -1입니다.
* `positioningItem` Number (optional) _OS X_ - 메뉴 팝업 시 마우스 커서에 바로
* `positioningItem` Number (optional) _macOS_ - 메뉴 팝업 시 마우스 커서에 바로
위치시킬 메뉴 아이템의 인덱스. 기본값은 -1입니다.
메뉴를 `browserWindow` 내부 팝업으로 표시합니다. 옵션으로 메뉴를 표시할 `(x,y)`
좌표를 지정할 수 있습니다. 따로 좌표를 지정하지 않은 경우 마우스 커서 위치에 표시됩니다.
`positioningItem` 속성은 메뉴 팝업 시 마우스 커서에 바로 위치시킬 메뉴 아이템의
인덱스입니다. (OS X에서만 지원합니다)
인덱스입니다. (macOS에서만 지원합니다)
### `menu.append(menuItem)`
@ -264,15 +294,15 @@ OS X의 네이티브 액션에 대해 자세히 알아보려면
메뉴가 가지고 있는 메뉴 아이템들의 배열입니다.
## OS X 어플리케이션 메뉴에 대해 알아 둬야 할 것들
## macOS 애플리케이션 메뉴에 대해 알아 둬야 할 것들
OS X에선 Windows, Linux와 달리 완전히 다른 어플리케이션 메뉴 스타일을 가지고 있습니다.
그래서 플리케이션을 네이티브처럼 작동할 수 있도록 하기 위해 다음 몇 가지 유의 사항을
macOS에선 Windows, Linux와 달리 완전히 다른 애플리케이션 메뉴 스타일을 가지고 있습니다.
그래서 플리케이션을 네이티브처럼 작동할 수 있도록 하기 위해 다음 몇 가지 유의 사항을
숙지해야 합니다.
### 기본 메뉴
OS X`Services``Windows`와 같은 많은 시스템 지정 기본 메뉴가 있습니다. 기본
macOS엔 `Services``Windows`와 같은 많은 시스템 지정 기본 메뉴가 있습니다. 기본
메뉴를 만들려면 반드시 다음 리스트 중 한 가지를 선택하여 메뉴의 `role`로 지정해야
합니다. 그러면 Electron이 자동으로 인식하여 해당 메뉴를 기본 메뉴로 만듭니다:
@ -282,14 +312,14 @@ OS X엔 `Services`나 `Windows`와 같은 많은 시스템 지정 기본 메뉴
### 메뉴 아이템 기본 동작
OS X는 몇가지 메뉴 아이템에 대해 `About xxx`, `Hide xxx`, `Hide Others`와 같은
macOS는 몇가지 메뉴 아이템에 대해 `About xxx`, `Hide xxx`, `Hide Others`와 같은
기본 동작을 제공하고 있습니다. 메뉴 아이템의 기본 동작을 지정하려면 반드시 메뉴
아이템의 `role` 속성을 지정해야 합니다.
### 메인 메뉴의 이름
OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번째 라벨은 언제나 어플리케이션의
이름이 됩니다. 플리케이션 이름을 변경하려면 앱 번들내의 `Info.plist` 파일을 수정해야
macOS에선 지정한 애플리케이션 메뉴에 상관없이 메뉴의 첫번째 라벨은 언제나 애플리케이션의
이름이 됩니다. 플리케이션 이름을 변경하려면 앱 번들내의 `Info.plist` 파일을 수정해야
합니다. 자세한 내용은 [About Information Property List Files][AboutInformationPropertyListFiles] 문서를 참고하세요.
## 지정한 브라우저 윈도우에 메뉴 설정 (*Linux* *Windows*)

View file

@ -1,6 +1,6 @@
# nativeImage
> PNG 또는 JPG 파일을 사용하여 트레이, 독, 플리케이션 아이콘을 생성합니다.
> PNG 또는 JPG 파일을 사용하여 트레이, 독, 플리케이션 아이콘을 생성합니다.
Electron은 파일 경로 또는 `nativeImage` 인스턴스를 통해 이미지를 사용할 수 있는 API를
가지고 있습니다. `null`을 전달할 경우 빈 이미지가 생성됩니다.
@ -79,7 +79,7 @@ let appIcon = new Tray('/Users/somebody/images/icon.png');
가장 일반적으로 템플릿 이미지는 밝고 어두운 테마 색상으로 변경할 수 있는 메뉴 바 아이콘
등에 사용되고 있습니다.
**참고:** 템플릿 이미지는 OS X 운영체제만 지원합니다.
**참고:** 템플릿 이미지는 macOS 운영체제만 지원합니다.
템플릿 이미지를 지정하려면 다음 예시와 같이 파일명에 `Template` 문자열을 추가해야
합니다:
@ -101,6 +101,12 @@ let appIcon = new Tray('/Users/somebody/images/icon.png');
`path`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다.
```javascript
const nativeImage = require('electron').nativeImage;
let image = nativeImage.createFromPath('/Users/somebody/images/icon.png');
```
### `nativeImage.createFromBuffer(buffer[, scaleFactor])`
* `buffer` [Buffer][buffer]
@ -117,12 +123,7 @@ let appIcon = new Tray('/Users/somebody/images/icon.png');
## Instance Methods
`nativeImage` 인스턴스 객체에서 사용할 수 있는 메서드 입니다:
```javascript
const nativeImage = require('electron').nativeImage;
let image = nativeImage.createFromPath('/Users/somebody/images/icon.png');
```
`nativeImage` 인스턴스 객체에서 사용할 수 있는 메서드입니다.
### `image.toPng()`
@ -138,10 +139,10 @@ let image = nativeImage.createFromPath('/Users/somebody/images/icon.png');
이미지를 data URL로 반환합니다.
### `image.getNativeHandle()` _OS X_
### `image.getNativeHandle()` _macOS_
이미지의 네이티브 핸들 밑에 있는 C 포인터를 담은 [Buffer][buffer]을 반환합니다.
OS X에선, `NSImage` 인스턴스가 반환됩니다.
macOS에선, `NSImage` 인스턴스가 반환됩니다.
참고로 반환된 포인터는 복사본이 아닌 네이티브 이미지의 밑에 있는 약한 포인터이며,
따라서 반드시 관련된 `nativeImage` 인스턴스가 확실하게 유지되고 있는지를 인지해야

View file

@ -20,10 +20,10 @@ powerSaveBlocker.stop(id);
### `powerSaveBlocker.start(type)`
* `type` String - Power save blocker 종류
* `prevent-app-suspension` - 저전력 모드 등으로 인한 플리케이션 작동 중단을
* `prevent-app-suspension` - 저전력 모드 등으로 인한 플리케이션 작동 중단을
방지합니다. 시스템을 항시 활성화 상태로 만듭니다. 하지만 화면은 자동으로 꺼질 수
있습니다. 사용 예시: 파일 다운로드, 음악 재생 등.
* `prevent-display-sleep`- 슬립 모드 등으로 인한 플리케이션의 작동 중단을
* `prevent-display-sleep`- 슬립 모드 등으로 인한 플리케이션의 작동 중단을
방지합니다. 시스템을 항시 활성화 상태로 만들고 슬립 모드(화면 꺼짐)를 방지합니다.
사용 예시: 비디오 재생 등.

View file

@ -74,7 +74,7 @@ Causes the main thread of the current process crash.
Causes the main thread of the current process hang.
### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_
### `process.setFdLimit(maxDescriptors)` _macOS_ _Linux_
* `maxDescriptors` Integer
@ -133,7 +133,7 @@ On Windows / Linux:
현재 프로세스의 주 스레드를 중단시킵니다.
### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_
### `process.setFdLimit(maxDescriptors)` _macOS_ _Linux_
* `maxDescriptors` Integer

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