From 666aca7803d1287d4765adaa8408f41189b42b99 Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Thu, 16 Jul 2015 13:54:51 -0400 Subject: [PATCH 001/172] add function maintainAspectRatioOfInteriorContent to BrowserWindow in order to enforce an aspect ratio for an electron window --- atom/browser/api/atom_api_window.cc | 5 +++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 13 +++++++++++++ atom/browser/native_window.h | 7 +++++++ atom/browser/native_window_mac.mm | 27 +++++++++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index d5bce5891135..ae907b0669d5 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,6 +249,10 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } +void Window::MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight) { + window_->MaintainAspectRatioOfInteriorContent(aspectRatio, gfx::Size(extraWidth, extraHeight)); +} + void Window::SetBounds(const gfx::Rect& bounds) { window_->SetBounds(bounds); } @@ -498,6 +502,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) + .SetMethod("maintainAspectRatioOfInteriorContent", &Window::MaintainAspectRatioOfInteriorContent) .SetMethod("getBounds", &Window::GetBounds) .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 5cdb49e41bbf..8c27f5b36a6f 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,6 +95,7 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); + void MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 2a093cc81200..8e21876fdfa3 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -195,6 +195,19 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } +double NativeWindow::GetInteriorContentAspectRatio() { + return interiorContentAspectRatio; +} + +gfx::Size NativeWindow::GetInteriorContentExtraSize() { + return interiorContentExtraSize; +} + +void NativeWindow::MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize) { + interiorContentAspectRatio = aspectRatio; + interiorContentExtraSize = extraSize; +} + void NativeWindow::SetSize(const gfx::Size& size) { SetBounds(gfx::Rect(GetPosition(), size)); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ac7aa50c915..e9e159a7ea3b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -107,6 +107,9 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; + double GetInteriorContentAspectRatio(); + virtual gfx::Size GetInteriorContentExtraSize(); + virtual void MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); @@ -285,6 +288,10 @@ class NativeWindow : public content::WebContentsObserver, // Page's default zoom factor. double zoom_factor_; + // Used to maintain the aspect ratio of a view which is inside of the content view. + double interiorContentAspectRatio = 0.0; + gfx::Size interiorContentExtraSize; + // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c0d358bb8f72..de7e8ad77967 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -95,6 +95,33 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; shell_->NotifyWindowBlur(); } +- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize { + NSSize newSize = frameSize; + double interiorContentAspectRatio = shell_->GetInteriorContentAspectRatio(); + + if (interiorContentAspectRatio > 0.0) { + NSRect windowFrame = [sender frame]; + NSRect contentViewBounds = [[sender contentView] bounds]; + gfx::Size interiorContentExtraSize = shell_->GetInteriorContentExtraSize(); + double extraWidthPlusFrame = windowFrame.size.width - contentViewBounds.size.width + interiorContentExtraSize.width(); + double extraHeightPlusFrame = windowFrame.size.height - contentViewBounds.size.height + interiorContentExtraSize.height(); + + newSize.width = roundf(((frameSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + + // If the new width is less than the frame size use it as the primary constraint. This ensures that the value returned + // by this method will never be larger than the users requested window size. + if (newSize.width < frameSize.width) { + newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + } + else { + newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + } + } + + return newSize; +} + - (void)windowDidResize:(NSNotification*)notification { if (!shell_->has_frame()) shell_->ClipWebView(); From 10faf314d4ba72b62875ee603eb7154459f95dbc Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Thu, 16 Jul 2015 14:26:48 -0400 Subject: [PATCH 002/172] fix line length issue --- atom/browser/native_window.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index e9e159a7ea3b..248a8a5338d7 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -288,7 +288,8 @@ class NativeWindow : public content::WebContentsObserver, // Page's default zoom factor. double zoom_factor_; - // Used to maintain the aspect ratio of a view which is inside of the content view. + // Used to maintain the aspect ratio of a view which is inside of the + // content view. double interiorContentAspectRatio = 0.0; gfx::Size interiorContentExtraSize; From 7cdfa4443875aad549ef1d7eddbc9abeb481abab Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Thu, 16 Jul 2015 14:31:01 -0400 Subject: [PATCH 003/172] shorten names --- atom/browser/api/atom_api_window.cc | 6 +++--- atom/browser/api/atom_api_window.h | 2 +- atom/browser/native_window.cc | 2 +- atom/browser/native_window.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ae907b0669d5..85fbcb872bc0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,8 +249,8 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } -void Window::MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight) { - window_->MaintainAspectRatioOfInteriorContent(aspectRatio, gfx::Size(extraWidth, extraHeight)); +void Window::MaintainContentAspectRatio(double aspectRatio, double width, double height) { + window_->MaintainContentAspectRatio(aspectRatio, gfx::Size(width, height)); } void Window::SetBounds(const gfx::Rect& bounds) { @@ -502,7 +502,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) - .SetMethod("maintainAspectRatioOfInteriorContent", &Window::MaintainAspectRatioOfInteriorContent) + .SetMethod("maintainContentAspectRatio", &Window::MaintainContentAspectRatio) .SetMethod("getBounds", &Window::GetBounds) .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 8c27f5b36a6f..21f61b5d5e00 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,7 +95,7 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); - void MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight); + void MaintainContentAspectRatio(double aspectRatio, double width, double height); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 8e21876fdfa3..5014c041cf7b 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -203,7 +203,7 @@ gfx::Size NativeWindow::GetInteriorContentExtraSize() { return interiorContentExtraSize; } -void NativeWindow::MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize) { +void NativeWindow::MaintainContentAspectRatio(double aspectRatio, const gfx::Size& extraSize) { interiorContentAspectRatio = aspectRatio; interiorContentExtraSize = extraSize; } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 248a8a5338d7..b73ff47dbdf7 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -109,7 +109,7 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsFullscreen() const = 0; double GetInteriorContentAspectRatio(); virtual gfx::Size GetInteriorContentExtraSize(); - virtual void MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize); + virtual void MaintainContentAspectRatio(double aspectRatio, const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); From d0c61766409f5b23280142b06a34c15e462e6dcd Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Thu, 16 Jul 2015 14:45:27 -0400 Subject: [PATCH 004/172] wrap lines to meet Travis CI build requirements --- atom/browser/api/atom_api_window.cc | 6 ++++-- atom/browser/api/atom_api_window.h | 3 ++- atom/browser/native_window.cc | 3 ++- atom/browser/native_window.h | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 85fbcb872bc0..e6d4ff4d4134 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,7 +249,8 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } -void Window::MaintainContentAspectRatio(double aspectRatio, double width, double height) { +void Window::MaintainContentAspectRatio(double aspectRatio, + double width, double height) { window_->MaintainContentAspectRatio(aspectRatio, gfx::Size(width, height)); } @@ -502,7 +503,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) - .SetMethod("maintainContentAspectRatio", &Window::MaintainContentAspectRatio) + .SetMethod("maintainContentAspectRatio", + &Window::MaintainContentAspectRatio) .SetMethod("getBounds", &Window::GetBounds) .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 21f61b5d5e00..313892a6b286 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,7 +95,8 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); - void MaintainContentAspectRatio(double aspectRatio, double width, double height); + void MaintainContentAspectRatio(double aspectRatio, + double width, double height); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 5014c041cf7b..544bfad46870 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -203,7 +203,8 @@ gfx::Size NativeWindow::GetInteriorContentExtraSize() { return interiorContentExtraSize; } -void NativeWindow::MaintainContentAspectRatio(double aspectRatio, const gfx::Size& extraSize) { +void NativeWindow::MaintainContentAspectRatio(double aspectRatio, + const gfx::Size& extraSize) { interiorContentAspectRatio = aspectRatio; interiorContentExtraSize = extraSize; } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index b73ff47dbdf7..ee0628422270 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -109,7 +109,8 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsFullscreen() const = 0; double GetInteriorContentAspectRatio(); virtual gfx::Size GetInteriorContentExtraSize(); - virtual void MaintainContentAspectRatio(double aspectRatio, const gfx::Size& extraSize); + virtual void MaintainContentAspectRatio(double aspectRatio, + const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); From 6656afd57f70a06a71107a92d4848ad6c6a98d98 Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Fri, 17 Jul 2015 10:25:30 -0400 Subject: [PATCH 005/172] fix bug with computing the case where we should constrain via height --- atom/browser/native_window_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index de7e8ad77967..f543aae1628d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -114,8 +114,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); } else { - newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); } } From 73790fcef5ba66ffe3f195e342caeb09c136780f Mon Sep 17 00:00:00 2001 From: Matias Insaurralde Date: Sun, 19 Jul 2015 17:39:59 -0400 Subject: [PATCH 006/172] preparing README-es --- docs/README-es.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/README-es.md diff --git a/docs/README-es.md b/docs/README-es.md new file mode 100644 index 000000000000..16ecc3afd4b3 --- /dev/null +++ b/docs/README-es.md @@ -0,0 +1,68 @@ +## Guías + +* [Application distribution](tutorial/application-distribution.md) +* [Application packaging](tutorial/application-packaging.md) +* [Utilizando módulos nativos](tutorial/using-native-node-modules.md) +* [Depurando el proceso principal](tutorial/debugging-main-process.md) +* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver.md) +* [Extensión DevTools](tutorial/devtools-extension.md) +* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin.md) + +## Tutoriales + +* [Quick start](tutorial/quick-start.md) +* [Integración con el entorno de escritorio](tutorial/desktop-environment-integration.md) +* [Detección del evento en línea/fuera de línea](tutorial/online-offline-events.md) + +## API + +* [Sinopsis](api/synopsis.md) +* [Proceso](api/process.md) +* [Supported Chrome command line switches](api/chrome-command-line-switches.md) + +Elementos DOM customizados: + +* [`File` object](api/file-object.md) +* [`` tag](api/web-view-tag.md) +* [`window.open` function](api/window-open.md) + +Módulos para el proceso principal: + +* [app](api/app.md) +* [auto-updater](api/auto-updater.md) +* [browser-window](api/browser-window.md) +* [content-tracing](api/content-tracing.md) +* [dialog](api/dialog.md) +* [global-shortcut](api/global-shortcut.md) +* [ipc (main process)](api/ipc-main-process.md) +* [menu](api/menu.md) +* [menu-item](api/menu-item.md) +* [power-monitor](api/power-monitor.md) +* [power-save-blocker](api/power-save-blocker.md) +* [protocol](api/protocol.md) +* [tray](api/tray.md) + +Módulos para el renderer (página web): + +* [ipc (renderer)](api/ipc-renderer.md) +* [remote](api/remote.md) +* [web-frame](api/web-frame.md) + +Módulos para ambos procesos: + +* [clipboard](api/clipboard.md) +* [crash-reporter](api/crash-reporter.md) +* [native-image](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Desarrollo + +* [Guía de estilo](development/coding-style.md) +* [Estructura de directorio](development/source-code-directory-structure.md) +* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Build system overview](development/build-system-overview.md) +* [Build instructions (Mac)](development/build-instructions-mac.md) +* [Build instructions (Windows)](development/build-instructions-windows.md) +* [Build instructions (Linux)](development/build-instructions-linux.md) +* [Setting up symbol server in debugger](development/setting-up-symbol-server.md) From 58f1907579f28f66211ea0716ba94ec34f681d94 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 22 Jul 2015 13:54:39 +0530 Subject: [PATCH 007/172] protocol: copy headers from original request for custom request job --- atom/browser/net/adapter_request_job.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/atom/browser/net/adapter_request_job.cc b/atom/browser/net/adapter_request_job.cc index d9c9b467d48c..5f584c2f7314 100644 --- a/atom/browser/net/adapter_request_job.cc +++ b/atom/browser/net/adapter_request_job.cc @@ -131,10 +131,13 @@ void AdapterRequestJob::CreateHttpJobAndStart( void AdapterRequestJob::CreateJobFromProtocolHandlerAndStart() { real_job_ = protocol_handler_->MaybeCreateJob(request(), network_delegate()); - if (!real_job_.get()) + if (!real_job_.get()) { CreateErrorJobAndStart(net::ERR_NOT_IMPLEMENTED); - else + } else { + // Copy headers from original request. + real_job_->SetExtraRequestHeaders(request()->extra_request_headers()); real_job_->Start(); + } } } // namespace atom From 6d25c81bd1385f43c832e70787732dc265135ce9 Mon Sep 17 00:00:00 2001 From: "Michael S. Barthelemy" Date: Wed, 22 Jul 2015 10:23:31 -0400 Subject: [PATCH 008/172] changes requested for pull request #2250 into electron master --- atom/browser/api/atom_api_window.cc | 8 +++----- atom/browser/api/atom_api_window.h | 3 +-- atom/browser/native_window.cc | 16 ++++++++-------- atom/browser/native_window.h | 11 +++++------ atom/browser/native_window_mac.mm | 24 ++++++++++++------------ docs/api/browser-window.md | 11 +++++++++++ 6 files changed, 40 insertions(+), 33 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index e6d4ff4d4134..49a41cf51a93 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,9 +249,8 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } -void Window::MaintainContentAspectRatio(double aspectRatio, - double width, double height) { - window_->MaintainContentAspectRatio(aspectRatio, gfx::Size(width, height)); +void Window::SetAspectRatio(double aspectRatio, gfx::Size extraSize) { + window_->SetAspectRatio(aspectRatio, extraSize); } void Window::SetBounds(const gfx::Rect& bounds) { @@ -503,8 +502,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) - .SetMethod("maintainContentAspectRatio", - &Window::MaintainContentAspectRatio) + .SetMethod("setAspectRatio", &Window::SetAspectRatio) .SetMethod("getBounds", &Window::GetBounds) .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 313892a6b286..e0345bc2e3bf 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,8 +95,7 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); - void MaintainContentAspectRatio(double aspectRatio, - double width, double height); + void SetAspectRatio(double aspectRatio, gfx::Size extraSize); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 544bfad46870..56999af945c5 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -195,18 +195,18 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } -double NativeWindow::GetInteriorContentAspectRatio() { - return interiorContentAspectRatio; +double NativeWindow::GetAspectRatio() { + return aspectRatio_; } -gfx::Size NativeWindow::GetInteriorContentExtraSize() { - return interiorContentExtraSize; +gfx::Size NativeWindow::GetAspectRatioExtraSize() { + return aspectRatioExtraSize_; } -void NativeWindow::MaintainContentAspectRatio(double aspectRatio, - const gfx::Size& extraSize) { - interiorContentAspectRatio = aspectRatio; - interiorContentExtraSize = extraSize; +void NativeWindow::SetAspectRatio(double aspectRatio, + const gfx::Size& extraSize) { + aspectRatio_ = aspectRatio; + aspectRatioExtraSize_ = extraSize; } void NativeWindow::SetSize(const gfx::Size& size) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index ee0628422270..cc0bd7b8f5a2 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -107,10 +107,9 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; - double GetInteriorContentAspectRatio(); - virtual gfx::Size GetInteriorContentExtraSize(); - virtual void MaintainContentAspectRatio(double aspectRatio, - const gfx::Size& extraSize); + double GetAspectRatio(); + virtual gfx::Size GetAspectRatioExtraSize(); + virtual void SetAspectRatio(double aspectRatio, const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); @@ -291,8 +290,8 @@ class NativeWindow : public content::WebContentsObserver, // Used to maintain the aspect ratio of a view which is inside of the // content view. - double interiorContentAspectRatio = 0.0; - gfx::Size interiorContentExtraSize; + double aspectRatio_ = 0.0; + gfx::Size aspectRatioExtraSize_; // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f543aae1628d..9c13518c302d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -97,25 +97,25 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize { NSSize newSize = frameSize; - double interiorContentAspectRatio = shell_->GetInteriorContentAspectRatio(); + double aspectRatio = shell_->GetAspectRatio(); - if (interiorContentAspectRatio > 0.0) { - NSRect windowFrame = [sender frame]; - NSRect contentViewBounds = [[sender contentView] bounds]; - gfx::Size interiorContentExtraSize = shell_->GetInteriorContentExtraSize(); - double extraWidthPlusFrame = windowFrame.size.width - contentViewBounds.size.width + interiorContentExtraSize.width(); - double extraHeightPlusFrame = windowFrame.size.height - contentViewBounds.size.height + interiorContentExtraSize.height(); + if (aspectRatio > 0.0) { + gfx::Size windowFrameSize = shell_->GetSize(); + gfx::Size contentViewSize = shell_->GetContentSize(); + gfx::Size aspectRatioExtraSize = shell_->GetAspectRatioExtraSize(); + double extraWidthPlusFrame = windowFrameSize.width() - contentViewSize.width() + aspectRatioExtraSize.width(); + double extraHeightPlusFrame = windowFrameSize.height() - contentViewSize.height() + aspectRatioExtraSize.height(); - newSize.width = roundf(((frameSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + newSize.width = roundf(((frameSize.height - extraHeightPlusFrame) * aspectRatio) + extraWidthPlusFrame); // If the new width is less than the frame size use it as the primary constraint. This ensures that the value returned // by this method will never be larger than the users requested window size. - if (newSize.width < frameSize.width) { - newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + if (newSize.width <= frameSize.width) { + newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / aspectRatio) + extraHeightPlusFrame); } else { - newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); - newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / aspectRatio) + extraHeightPlusFrame); + newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * aspectRatio) + extraWidthPlusFrame); } } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 48a118ffa3c2..25e2ba2958e7 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -361,6 +361,17 @@ Sets whether the window should be in fullscreen mode. Returns whether the window is in fullscreen mode. +### BrowserWindow.setAspectRatio(aspectRatio, [extraSize]) + +* `aspectRatio` The aspect ratio we want to maintain for some portion of the content view. +* `rect` Object - The extra size to not be included in the aspect ratio to be maintained. + * `width` Integer + * `height` Integer + +This will have a window maintain an aspect ratio. The extra size allows a developer to be able to have space, specifified in pixels, not included within the aspect ratio calculations. This API already takes into account the difference between a window's size and it's content size. + +Consider a normal window with an HD video player and associated controls. Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within the player itself we would call this function with arguments of 16/9 and [ 40, 50 ]. The second argument doesn't care where the extra width and height are within the content view — only that they exist. Just sum any extra width and height areas you have within the overall content view. + ### BrowserWindow.setBounds(options) * `options` Object From d701e1aa40438cb2403eb3fac69138ee78fd6f10 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Wed, 22 Jul 2015 18:13:50 +0300 Subject: [PATCH 009/172] Update dialog.md Added a comment about the fact that on Windows, the "question" message box uses the same icon as the "info" message box (Electron uses the task dialog API instead of the message box API). This is because Microsoft's API doesn't supply a default question icon (see `pszIcon` in https://msdn.microsoft.com/en-us/library/windows/desktop/bb760540(v=vs.85).aspx). --- docs/api/dialog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 9e123b381c51..f6b65a1bb06c 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -70,7 +70,7 @@ will be passed via `callback(filename)` * `browserWindow` BrowserWindow * `options` Object - * `type` String - Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"` + * `type` String - Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"`. On Windows, "question" displays the same icon as "info", unless if you set an icon using the "icon" option * `buttons` Array - Array of texts for buttons * `title` String - Title of the message box, some platforms will not show it * `message` String - Content of the message box From a1ec07e07e6d5fd8735746e19357e70c0276dce8 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 22 Jul 2015 21:45:08 +0530 Subject: [PATCH 010/172] read post-filtered data when filters are present --- atom/browser/net/adapter_request_job.cc | 11 ++++++++++- atom/browser/net/adapter_request_job.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/atom/browser/net/adapter_request_job.cc b/atom/browser/net/adapter_request_job.cc index 5f584c2f7314..2be25b657513 100644 --- a/atom/browser/net/adapter_request_job.cc +++ b/atom/browser/net/adapter_request_job.cc @@ -43,7 +43,11 @@ bool AdapterRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read) { DCHECK(!real_job_.get()); - return real_job_->ReadRawData(buf, buf_size, bytes_read); + // Read post-filtered data if available. + if (real_job_->HasFilter()) + return real_job_->Read(buf, buf_size, bytes_read); + else + return real_job_->ReadRawData(buf, buf_size, bytes_read); } bool AdapterRequestJob::IsRedirectResponse(GURL* location, @@ -75,6 +79,11 @@ int AdapterRequestJob::GetResponseCode() const { return real_job_->GetResponseCode(); } +void AdapterRequestJob::GetLoadTimingInfo( + net::LoadTimingInfo* load_timing_info) const { + real_job_->GetLoadTimingInfo(load_timing_info); +} + base::WeakPtr AdapterRequestJob::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } diff --git a/atom/browser/net/adapter_request_job.h b/atom/browser/net/adapter_request_job.h index 768718584d03..bca549a2eef2 100644 --- a/atom/browser/net/adapter_request_job.h +++ b/atom/browser/net/adapter_request_job.h @@ -46,6 +46,8 @@ class AdapterRequestJob : public net::URLRequestJob { bool GetCharset(std::string* charset) override; void GetResponseInfo(net::HttpResponseInfo* info) override; int GetResponseCode() const override; + void GetLoadTimingInfo( + net::LoadTimingInfo* load_timing_info) const override; base::WeakPtr GetWeakPtr(); From 97c90d31d3866fa2fc44bd2f56d5de9e6203ffd8 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 22 Jul 2015 21:54:12 +0530 Subject: [PATCH 011/172] get jsprotocolhandler in IO thread --- atom/browser/api/atom_api_protocol.cc | 13 +++++++++---- atom/browser/net/adapter_request_job.cc | 6 +----- atom/browser/net/adapter_request_job.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index d7af58802792..53aef95b7657 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -80,16 +80,13 @@ class CustomProtocolRequestJob : public AdapterRequestJob { registry_(registry) { } - // AdapterRequestJob: - void GetJobTypeInUI() override { + void GetJobTypeInUI(const Protocol::JsProtocolHandler& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); v8::Locker locker(registry_->isolate()); v8::HandleScope handle_scope(registry_->isolate()); // Call the JS handler. - Protocol::JsProtocolHandler callback = - registry_->GetProtocolHandler(request()->url().scheme()); v8::Local result = callback.Run(request()); // Determine the type of the job we are going to create. @@ -172,6 +169,14 @@ class CustomProtocolRequestJob : public AdapterRequestJob { GetWeakPtr(), net::ERR_NOT_IMPLEMENTED)); } + // AdapterRequestJob: + void GetJobType() override { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&CustomProtocolRequestJob::GetJobTypeInUI, + base::Unretained(this), + registry_->GetProtocolHandler(request()->url().scheme()))); + } + private: Protocol* registry_; // Weak, the Protocol class is expected to live forever. }; diff --git a/atom/browser/net/adapter_request_job.cc b/atom/browser/net/adapter_request_job.cc index 2be25b657513..5c41c6f65aac 100644 --- a/atom/browser/net/adapter_request_job.cc +++ b/atom/browser/net/adapter_request_job.cc @@ -27,11 +27,7 @@ AdapterRequestJob::AdapterRequestJob(ProtocolHandler* protocol_handler, void AdapterRequestJob::Start() { DCHECK(!real_job_.get()); - content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, - base::Bind(&AdapterRequestJob::GetJobTypeInUI, - weak_factory_.GetWeakPtr())); + GetJobType(); } void AdapterRequestJob::Kill() { diff --git a/atom/browser/net/adapter_request_job.h b/atom/browser/net/adapter_request_job.h index bca549a2eef2..b1d28b1446c1 100644 --- a/atom/browser/net/adapter_request_job.h +++ b/atom/browser/net/adapter_request_job.h @@ -54,7 +54,7 @@ class AdapterRequestJob : public net::URLRequestJob { ProtocolHandler* default_protocol_handler() { return protocol_handler_; } // Override this function to determine which job should be started. - virtual void GetJobTypeInUI() = 0; + virtual void GetJobType() = 0; void CreateErrorJobAndStart(int error_code); void CreateStringJobAndStart(const std::string& mime_type, From df35700b940369289371cc92e4b66c47ddad6c76 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 10:07:58 +0800 Subject: [PATCH 012/172] Style fixes * Use under_score for variable names in C++ * Use const& when possible * Line length <= 80 --- atom/browser/api/atom_api_window.cc | 4 +-- atom/browser/api/atom_api_window.h | 2 +- atom/browser/native_window.cc | 29 ++++++++++----------- atom/browser/native_window.h | 12 +++++---- atom/browser/native_window_mac.mm | 39 ++++++++++++++++++----------- 5 files changed, 50 insertions(+), 36 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 49a41cf51a93..c4e6b06af06f 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,8 +249,8 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } -void Window::SetAspectRatio(double aspectRatio, gfx::Size extraSize) { - window_->SetAspectRatio(aspectRatio, extraSize); +void Window::SetAspectRatio(double aspect_ratio, const gfx::Size& extraSize) { + window_->SetAspectRatio(aspect_ratio, extraSize); } void Window::SetBounds(const gfx::Rect& bounds) { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index e0345bc2e3bf..f807ab135f28 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,7 +95,7 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); - void SetAspectRatio(double aspectRatio, gfx::Size extraSize); + void SetAspectRatio(double aspect_ratio, const gfx::Size& extraSize); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 56999af945c5..c03ab1ac24a4 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -85,6 +85,7 @@ NativeWindow::NativeWindow( node_integration_(true), has_dialog_attached_(false), zoom_factor_(1.0), + aspect_ratio_(0.0), inspectable_web_contents_(inspectable_web_contents), weak_factory_(this) { inspectable_web_contents->GetView()->SetDelegate(this); @@ -195,20 +196,6 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } -double NativeWindow::GetAspectRatio() { - return aspectRatio_; -} - -gfx::Size NativeWindow::GetAspectRatioExtraSize() { - return aspectRatioExtraSize_; -} - -void NativeWindow::SetAspectRatio(double aspectRatio, - const gfx::Size& extraSize) { - aspectRatio_ = aspectRatio; - aspectRatioExtraSize_ = extraSize; -} - void NativeWindow::SetSize(const gfx::Size& size) { SetBounds(gfx::Rect(GetPosition(), size)); } @@ -260,6 +247,20 @@ bool NativeWindow::IsMenuBarVisible() { return true; } +double NativeWindow::GetAspectRatio() { + return aspect_ratio_; +} + +gfx::Size NativeWindow::GetAspectRatioExtraSize() { + return aspect_ratio_extraSize_; +} + +void NativeWindow::SetAspectRatio(double aspect_ratio, + const gfx::Size& extra_size) { + aspect_ratio_ = aspect_ratio; + aspect_ratio_extraSize_ = extra_size; +} + bool NativeWindow::HasModalDialog() { return has_dialog_attached_; } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index cc0bd7b8f5a2..b9c2486b791b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -107,9 +107,6 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; - double GetAspectRatio(); - virtual gfx::Size GetAspectRatioExtraSize(); - virtual void SetAspectRatio(double aspectRatio, const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); @@ -166,6 +163,11 @@ class NativeWindow : public content::WebContentsObserver, virtual void SetMenuBarVisibility(bool visible); virtual bool IsMenuBarVisible(); + // Set the aspect ratio when resizing window. + double GetAspectRatio(); + gfx::Size GetAspectRatioExtraSize(); + void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size); + base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -290,8 +292,8 @@ class NativeWindow : public content::WebContentsObserver, // Used to maintain the aspect ratio of a view which is inside of the // content view. - double aspectRatio_ = 0.0; - gfx::Size aspectRatioExtraSize_; + double aspect_ratio_; + gfx::Size aspect_ratio_extraSize_; // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index b69785045a8b..d5f12bde13dd 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -95,27 +95,38 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; shell_->NotifyWindowBlur(); } -- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize { +- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize { NSSize newSize = frameSize; double aspectRatio = shell_->GetAspectRatio(); if (aspectRatio > 0.0) { - gfx::Size windowFrameSize = shell_->GetSize(); - gfx::Size contentViewSize = shell_->GetContentSize(); - gfx::Size aspectRatioExtraSize = shell_->GetAspectRatioExtraSize(); - double extraWidthPlusFrame = windowFrameSize.width() - contentViewSize.width() + aspectRatioExtraSize.width(); - double extraHeightPlusFrame = windowFrameSize.height() - contentViewSize.height() + aspectRatioExtraSize.height(); + gfx::Size windowSize = shell_->GetSize(); + gfx::Size contentSize = shell_->GetContentSize(); + gfx::Size extraSize = shell_->GetAspectRatioExtraSize(); - newSize.width = roundf(((frameSize.height - extraHeightPlusFrame) * aspectRatio) + extraWidthPlusFrame); + double extraWidthPlusFrame = + windowSize.width() - contentSize.width() + extraSize.width(); + double extraHeightPlusFrame = + windowSize.height() - contentSize.height() + extraSize.height(); - // If the new width is less than the frame size use it as the primary constraint. This ensures that the value returned - // by this method will never be larger than the users requested window size. + newSize.width = + roundf((frameSize.height - extraHeightPlusFrame) * aspectRatio + + extraWidthPlusFrame); + + // If the new width is less than the frame size use it as the primary + // constraint. This ensures that the value returned by this method will + // never be larger than the users requested window size. if (newSize.width <= frameSize.width) { - newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / aspectRatio) + extraHeightPlusFrame); - } - else { - newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / aspectRatio) + extraHeightPlusFrame); - newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * aspectRatio) + extraWidthPlusFrame); + newSize.height = + roundf((newSize.width - extraWidthPlusFrame) / aspectRatio + + extraHeightPlusFrame); + } else { + newSize.height = + roundf((frameSize.width - extraWidthPlusFrame) / aspectRatio + + extraHeightPlusFrame); + newSize.width = + roundf((newSize.height - extraHeightPlusFrame) * aspectRatio + + extraWidthPlusFrame); } } From 72eb87a6312316ba595c2709348f12d5c8cd52bc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 10:14:02 +0800 Subject: [PATCH 013/172] Make the extraSize of BrowserWindow.setAspectRatio optional --- atom/browser/api/atom_api_window.cc | 10 ++++++---- atom/browser/api/atom_api_window.h | 2 +- docs/api/browser-window.md | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c4e6b06af06f..5f7c2503fced 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,10 +249,6 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } -void Window::SetAspectRatio(double aspect_ratio, const gfx::Size& extraSize) { - window_->SetAspectRatio(aspect_ratio, extraSize); -} - void Window::SetBounds(const gfx::Rect& bounds) { window_->SetBounds(bounds); } @@ -455,6 +451,12 @@ void Window::ShowDefinitionForSelection() { } #endif +void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) { + gfx::Size extra_size; + args->GetNext(&extra_size); + window_->SetAspectRatio(aspect_ratio, extra_size); +} + void Window::SetVisibleOnAllWorkspaces(bool visible) { return window_->SetVisibleOnAllWorkspaces(visible); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index f807ab135f28..cc2b3a64b5e9 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,7 +95,6 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); - void SetAspectRatio(double aspect_ratio, const gfx::Size& extraSize); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); @@ -135,6 +134,7 @@ class Window : public mate::TrackableObject, bool IsMenuBarAutoHide(); void SetMenuBarVisibility(bool visible); bool IsMenuBarVisible(); + void SetAspectRatio(double aspect_ratio, mate::Arguments* args); #if defined(OS_MACOSX) void ShowDefinitionForSelection(); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 445265e54471..c8fc39a53f1f 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -361,7 +361,7 @@ Sets whether the window should be in fullscreen mode. Returns whether the window is in fullscreen mode. -### BrowserWindow.setAspectRatio(aspectRatio, [extraSize]) +### BrowserWindow.setAspectRatio(aspectRatio[, extraSize]) * `aspectRatio` The aspect ratio we want to maintain for some portion of the content view. * `rect` Object - The extra size to not be included in the aspect ratio to be maintained. @@ -372,6 +372,8 @@ This will have a window maintain an aspect ratio. The extra size allows a develo Consider a normal window with an HD video player and associated controls. Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within the player itself we would call this function with arguments of 16/9 and [ 40, 50 ]. The second argument doesn't care where the extra width and height are within the content view — only that they exist. Just sum any extra width and height areas you have within the overall content view. +__Note__: This API is only implemented on OS X. + ### BrowserWindow.setBounds(options) * `options` Object From eb92e9cdd80c518c2ac2bb87287cfdf9eb4dee0a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 13:46:34 +0800 Subject: [PATCH 014/172] Use node::MakeCallback to emit events in C++ Fix #2165 --- atom/common/event_emitter_caller.cc | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/atom/common/event_emitter_caller.cc b/atom/common/event_emitter_caller.cc index 85f56a233731..3dbdc9db956d 100644 --- a/atom/common/event_emitter_caller.cc +++ b/atom/common/event_emitter_caller.cc @@ -4,6 +4,8 @@ #include "atom/common/event_emitter_caller.h" +#include "atom/common/node_includes.h" + namespace mate { namespace internal { @@ -11,21 +13,8 @@ namespace internal { v8::Local CallEmitWithArgs(v8::Isolate* isolate, v8::Local obj, ValueVector* args) { - v8::Local emit_name = StringToSymbol(isolate, "emit"); - v8::Local emit = obj->Get(emit_name); - if (emit.IsEmpty() || !emit->IsFunction()) { - isolate->ThrowException(v8::Exception::TypeError( - StringToV8(isolate, "\"emit\" is not a function"))); - return v8::Undefined(isolate); - } - - v8::MaybeLocal result = emit.As()->Call( - isolate->GetCurrentContext(), obj, args->size(), &args->front()); - if (result.IsEmpty()) { - return v8::Undefined(isolate); - } - - return result.ToLocalChecked(); + return node::MakeCallback( + isolate, obj, "emit", args->size(), &args->front()); } } // namespace internal From da724d65d703a34a379b29527bbbc20dcbd4e4f4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 14:16:43 +0800 Subject: [PATCH 015/172] Add |options| for ShowMessageBox --- atom/browser/api/atom_api_dialog.cc | 7 ++++--- atom/browser/api/lib/dialog.coffee | 1 + atom/browser/ui/message_box.h | 7 +++++++ atom/browser/ui/message_box_gtk.cc | 2 ++ atom/browser/ui/message_box_mac.mm | 2 ++ atom/browser/ui/message_box_win.cc | 2 ++ 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index b5fd655d6f26..695c11e336ee 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -42,6 +42,7 @@ namespace { void ShowMessageBox(int type, const std::vector& buttons, int cancel_id, + int options, const std::vector& texts, const gfx::ImageSkia& icon, atom::NativeWindow* window, @@ -59,11 +60,11 @@ void ShowMessageBox(int type, peek, &callback)) { atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id, - title, message, detail, icon, callback); + options, title, message, detail, icon, callback); } else { int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type, - buttons, cancel_id, title, message, - detail, icon); + buttons, cancel_id, options, title, + message, detail, icon); args->Return(chosen); } } diff --git a/atom/browser/api/lib/dialog.coffee b/atom/browser/api/lib/dialog.coffee index 7a60b7f846e0..35ef6240918c 100644 --- a/atom/browser/api/lib/dialog.coffee +++ b/atom/browser/api/lib/dialog.coffee @@ -104,6 +104,7 @@ module.exports = binding.showMessageBox messageBoxType, options.buttons, options.cancelId, + 0, [options.title, options.message, options.detail], options.icon, window, diff --git a/atom/browser/ui/message_box.h b/atom/browser/ui/message_box.h index 817da2c56998..22cfa267b256 100644 --- a/atom/browser/ui/message_box.h +++ b/atom/browser/ui/message_box.h @@ -27,12 +27,18 @@ enum MessageBoxType { MESSAGE_BOX_TYPE_QUESTION, }; +enum MessageBoxOptions { + MESSAGE_BOX_NONE = 0, + MESSAGE_BOX_NO_LINKS = 1 << 0, +}; + typedef base::Callback MessageBoxCallback; int ShowMessageBox(NativeWindow* parent_window, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, @@ -42,6 +48,7 @@ void ShowMessageBox(NativeWindow* parent_window, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, diff --git a/atom/browser/ui/message_box_gtk.cc b/atom/browser/ui/message_box_gtk.cc index 07695d49845c..41682190e60e 100644 --- a/atom/browser/ui/message_box_gtk.cc +++ b/atom/browser/ui/message_box_gtk.cc @@ -162,6 +162,7 @@ int ShowMessageBox(NativeWindow* parent, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, @@ -174,6 +175,7 @@ void ShowMessageBox(NativeWindow* parent, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index 8fe3b7d060c3..e518af653da4 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -95,6 +95,7 @@ int ShowMessageBox(NativeWindow* parent_window, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, @@ -127,6 +128,7 @@ void ShowMessageBox(NativeWindow* parent_window, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index dae518deb4dc..d8e088072306 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -163,6 +163,7 @@ int ShowMessageBox(NativeWindow* parent, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, @@ -190,6 +191,7 @@ void ShowMessageBox(NativeWindow* parent, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, From 1578d2fda9b00616b12e7592a6dede87c2f8bf0a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 15:00:42 +0800 Subject: [PATCH 016/172] Allow the C++ JS binding function to accept arbitrary long arguments --- atom/browser/api/atom_api_dialog.cc | 11 +++-------- atom/browser/api/lib/dialog.coffee | 4 +++- vendor/native_mate | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 695c11e336ee..47021407e1ea 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -43,17 +43,12 @@ void ShowMessageBox(int type, const std::vector& buttons, int cancel_id, int options, - const std::vector& texts, + const std::string& title, + const std::string& message, + const std::string& detail, const gfx::ImageSkia& icon, atom::NativeWindow* window, mate::Arguments* args) { - // FIXME We are exceeding the parameters limit of base::Bind here, so we have - // to pass some parameters in an array. We should remove this once we have - // variadic template support in base::Bind. - const std::string& title = texts[0]; - const std::string& message = texts[1]; - const std::string& detail = texts[2]; - v8::Local peek = args->PeekNext(); atom::MessageBoxCallback callback; if (mate::Converter::FromV8(args->isolate(), diff --git a/atom/browser/api/lib/dialog.coffee b/atom/browser/api/lib/dialog.coffee index 35ef6240918c..a1dcaafe78fe 100644 --- a/atom/browser/api/lib/dialog.coffee +++ b/atom/browser/api/lib/dialog.coffee @@ -105,7 +105,9 @@ module.exports = options.buttons, options.cancelId, 0, - [options.title, options.message, options.detail], + options.title, + options.message, + options.detail, options.icon, window, callback diff --git a/vendor/native_mate b/vendor/native_mate index 41cd6d13c9c9..656e403f0102 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 41cd6d13c9c9be164f427864277f3cc36b69eb39 +Subproject commit 656e403f0102c59428261c1eaad22912d2bbd3c5 From cc2a9f617d755da98e915d772ad8813b2feb0d4a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 17:20:43 +0800 Subject: [PATCH 017/172] Add noLink option for showMessageBox --- atom/browser/api/lib/dialog.coffee | 7 ++++++- atom/browser/ui/message_box.h | 4 ++-- atom/browser/ui/message_box_win.cc | 7 +++++-- docs/api/dialog.md | 7 ++++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/lib/dialog.coffee b/atom/browser/api/lib/dialog.coffee index a1dcaafe78fe..0843af04282e 100644 --- a/atom/browser/api/lib/dialog.coffee +++ b/atom/browser/api/lib/dialog.coffee @@ -11,6 +11,9 @@ fileDialogProperties = messageBoxTypes = ['none', 'info', 'warning', 'error', 'question'] +messageBoxOptions = + noLink: 1 << 0 + parseArgs = (window, options, callback) -> unless window is null or window?.constructor is BrowserWindow # Shift. @@ -101,10 +104,12 @@ module.exports = options.cancelId = i break + flags = if options.noLink then messageBoxOptions.noLink else 0 + binding.showMessageBox messageBoxType, options.buttons, options.cancelId, - 0, + flags, options.title, options.message, options.detail, diff --git a/atom/browser/ui/message_box.h b/atom/browser/ui/message_box.h index 22cfa267b256..92052d3de4a4 100644 --- a/atom/browser/ui/message_box.h +++ b/atom/browser/ui/message_box.h @@ -28,8 +28,8 @@ enum MessageBoxType { }; enum MessageBoxOptions { - MESSAGE_BOX_NONE = 0, - MESSAGE_BOX_NO_LINKS = 1 << 0, + MESSAGE_BOX_NONE = 0, + MESSAGE_BOX_NO_LINK = 1 << 0, }; typedef base::Callback MessageBoxCallback; diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index d8e088072306..194a0d79f8f8 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -72,6 +72,7 @@ int ShowMessageBoxUTF16(HWND parent, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const base::string16& title, const base::string16& message, const base::string16& detail, @@ -126,7 +127,8 @@ int ShowMessageBoxUTF16(HWND parent, if (dialog_buttons.size() > 0) { config.pButtons = &dialog_buttons.front(); config.cButtons = dialog_buttons.size(); - config.dwFlags |= TDF_USE_COMMAND_LINKS; // custom buttons as links. + if (!(options & MESSAGE_BOX_NO_LINK)) + config.dwFlags |= TDF_USE_COMMAND_LINKS; // custom buttons as links. } int id = 0; @@ -181,6 +183,7 @@ int ShowMessageBox(NativeWindow* parent, type, utf16_buttons, cancel_id, + options, base::UTF8ToUTF16(title), base::UTF8ToUTF16(message), base::UTF8ToUTF16(detail), @@ -214,7 +217,7 @@ void ShowMessageBox(NativeWindow* parent, } void ShowErrorBox(const base::string16& title, const base::string16& content) { - ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, 0, L"Error", title, + ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, 0, 0, L"Error", title, content, gfx::ImageSkia()); } diff --git a/docs/api/dialog.md b/docs/api/dialog.md index f6b65a1bb06c..d9336c0c8a3a 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -80,7 +80,12 @@ will be passed via `callback(filename)` instead of clicking the buttons of the dialog. By default it is the index of the buttons that have "cancel" or "no" as label, or 0 if there is no such buttons. On OS X and Windows the index of "Cancel" button will always be - used as `cancelId`, not matter whether it is already specified. + used as `cancelId`, not matter whether it is already specified + * `noLink` Boolean - On Windows Electron would try to figure out which ones of + the `buttons` are common buttons (like "Cancel" or "Yes"), and show the + others as command links in the dialog, this can make the dialog appear in + the style of modern Windows apps. If you don't like this behavior, you can + specify `noLink` to `true` * `callback` Function Shows a message box, it will block until the message box is closed. It returns From 6c44553456a17ec1db55fb4edb5bd31e0298fd90 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Jul 2015 17:28:04 +0800 Subject: [PATCH 018/172] Show all buttons as custom buttons when noLink is specified --- atom/browser/ui/message_box_win.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index 194a0d79f8f8..58d1badc3bfd 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -123,7 +123,12 @@ int ShowMessageBoxUTF16(HWND parent, // and custom buttons in pButtons. std::map id_map; std::vector dialog_buttons; - MapToCommonID(buttons, &id_map, &config.dwCommonButtons, &dialog_buttons); + if (options & MESSAGE_BOX_NO_LINK) { + for (size_t i = 0; i < buttons.size(); ++i) + dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()}); + } else { + MapToCommonID(buttons, &id_map, &config.dwCommonButtons, &dialog_buttons); + } if (dialog_buttons.size() > 0) { config.pButtons = &dialog_buttons.front(); config.cButtons = dialog_buttons.size(); @@ -146,13 +151,14 @@ void RunMessageBoxInNewThread(base::Thread* thread, MessageBoxType type, const std::vector& buttons, int cancel_id, + int options, const std::string& title, const std::string& message, const std::string& detail, const gfx::ImageSkia& icon, const MessageBoxCallback& callback) { - int result = ShowMessageBox(parent, type, buttons, cancel_id, title, message, - detail, icon); + int result = ShowMessageBox(parent, type, buttons, cancel_id, options, title, + message, detail, icon); content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); content::BrowserThread::DeleteSoon( @@ -212,8 +218,8 @@ void ShowMessageBox(NativeWindow* parent, unretained->message_loop()->PostTask( FROM_HERE, base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained), - parent, type, buttons, cancel_id, title, message, detail, icon, - callback)); + parent, type, buttons, cancel_id, options, title, message, + detail, icon, callback)); } void ShowErrorBox(const base::string16& title, const base::string16& content) { From 452619990e8748ff1d95406d7369b43e65166770 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 17:55:57 +0100 Subject: [PATCH 019/172] Improve grammar and punctuation of accelerator.md Improve the grammar, sentence structure, punctuation and formatting of `accelerator.md`. --- docs/api/accelerator.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index a9755ed653b0..8c1b3e70ce4c 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -1,6 +1,6 @@ # Accelerator -An accelerator is string that represents a keyboard shortcut, it can contain +An accelerator is a string that represents a keyboard shortcut. It can contain multiple modifiers and key codes, combined by the `+` character. Examples: @@ -10,11 +10,11 @@ Examples: ## Platform notice -On Linux and Windows, the `Command` key would not have any effect, you can +On Linux and Windows, the `Command` key does not have any effect so use `CommandOrControl` which represents `Command` on OS X and `Control` on Linux and Windows to define some accelerators. -The `Super` key is mapped to the `Windows` key on Windows and Linux and +The `Super` key is mapped onto the `Windows` key on Windows and Linux and onto `Cmd` on OS X. ## Available modifiers From d138c2970c2711306ddae1e9d0fa953be2227d60 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 17:57:42 +0100 Subject: [PATCH 020/172] Improve grammar and punctuation of auto-updater.md Improve the grammar, sentence structure, punctuation and formatting of `auto-updater.md`. --- docs/api/auto-updater.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 8da46e2083c9..a14e3ecd91f0 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -3,9 +3,9 @@ **This module has only been implemented for OS X.** Check out [atom/grunt-electron-installer](https://github.com/atom/grunt-electron-installer) -for building a Windows installer for your app. +to build a Windows installer for your app. -The `auto-updater` module is a simple wrap around the +The `auto-updater` module is a simple wrapper around the [Squirrel.Mac](https://github.com/Squirrel/Squirrel.Mac) framework. Squirrel.Mac requires that your `.app` folder is signed using the @@ -26,11 +26,11 @@ body so that your server has the context it needs in order to supply the most suitable update. The update JSON Squirrel requests should be dynamically generated based on -criteria in the request, and whether an update is required. Squirrel relies -on server side support for determining whether an update is required, see +criteria in the request and whether an update is required. Squirrel relies +on server-side support to determine whether an update is required. See [Server Support](#server-support). -Squirrel's installer is also designed to be fault tolerant, and ensure that any +Squirrel's installer is designed to be fault tolerant and ensures that any updates installed are valid. ## Update Requests @@ -40,11 +40,11 @@ update checking. `Accept: application/json` is added to the request headers because Squirrel is responsible for parsing the response. For the requirements imposed on the responses and the body format of an update -response see [Server Support](#server-support). +response, see [Server Support](#server-support). Your update request must *at least* include a version identifier so that the server can determine whether an update for this specific version is required. It -may also include other identifying criteria such as operating system version or +may also include other identifying criteria, such as operating system version or username, to allow the server to deliver as fine grained an update as you would like. @@ -64,7 +64,7 @@ autoUpdater.setFeedUrl('http://mycompany.com/myapp/latest?version=' + app.getVer Your server should determine whether an update is required based on the [Update Request](#update-requests) your client issues. -If an update is required your server should respond with a status code of +If an update is required, your server should respond with a status code of [200 OK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the [update JSON](#update-json-format) in the body. Squirrel **will** download and install this update, even if the version of the update is the same as the @@ -89,29 +89,29 @@ to the update request provided: } ``` -The only required key is "url", the others are optional. +The only required key is "url"; the others are optional. Squirrel will request "url" with `Accept: application/zip` and only supports installing ZIP updates. If future update formats are supported their MIME type will be added to the `Accept` header so that your server can return the appropriate format. -`pub_date` if present must be formatted according to ISO 8601. +`pub_date` (if present) must be formatted according to ISO 8601. ## Event: error * `event` Event * `message` String -Emitted when there is an error updating. +Emitted when there is an error while updating. ## Event: checking-for-update -Emitted when checking for update has started. +Emitted when checking for an update has started. ## Event: update-available -Emitted when there is an available update, the update would be downloaded +Emitted when there is an available update. The update is downloaded automatically. ## Event: update-not-available @@ -127,17 +127,17 @@ Emitted when there is no available update. * `updateUrl` String * `quitAndUpdate` Function -Emitted when update has been downloaded, calling `quitAndUpdate()` would restart +Emitted when an update has been downloaded. Calling `quitAndUpdate()` will restart the application and install the update. ## autoUpdater.setFeedUrl(url) * `url` String -Set the `url` and initialize the auto updater. The `url` could not be changed +Set the `url` and initialize the auto updater. The `url` cannot be changed once it is set. ## autoUpdater.checkForUpdates() -Ask the server whether there is an update, you have to call `setFeedUrl` before +Ask the server whether there is an update. You must call `setFeedUrl` before using this API. From adab7697006a3a402b99436be3a35e34a4ef1c76 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 17:59:51 +0100 Subject: [PATCH 021/172] Improve grammar and punctuation of `chrome-command-line-switches.md` Improve the grammar, sentence structure, punctuation and formatting of `chrome-command-line-switches.md` --- docs/api/chrome-command-line-switches.md | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index d55dea4c1b5a..94bb200168ff 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -1,8 +1,8 @@ # Supported Chrome command line switches -The following command lines switches in Chrome browser are also supported in -Electron, you can use [app.commandLine.appendSwitch][append-switch] to append -them in your app's main script before the [ready][ready] event of [app][app] +This page lists the command line switches used by the Chrome browser that are also supported by +Electron. You can use [app.commandLine.appendSwitch][append-switch] to append +them to your app's main script before the [ready][ready] event of [app][app] module is emitted: ```javascript @@ -17,11 +17,11 @@ app.on('ready', function() { ## --client-certificate=`path` -Sets `path` of client certificate file. +Sets the `path` of client certificate file. ## --ignore-connections-limit=`domains` -Ignore the connections limit for `domains` list seperated by `,`. +Ignore the connections limit for `domains` list separated by `,`. ## --disable-http-cache @@ -29,11 +29,11 @@ Disables the disk cache for HTTP requests. ## --remote-debugging-port=`port` -Enables remote debug over HTTP on the specified `port`. +Enables remote debugging over HTTP on the specified `port`. ## --proxy-server=`address:port` -Uses a specified proxy server, overrides system settings. This switch only +Use a specified proxy server, which overrides the system setting. This switch only affects HTTP and HTTPS requests. ## --proxy-pac-url=`url` @@ -42,12 +42,12 @@ Uses the PAC script at the specified `url`. ## --no-proxy-server -Don't use a proxy server, always make direct connections. Overrides any other +Don't use a proxy server and always make direct connections. Overrides any other proxy server flags that are passed. ## --host-rules=`rules` -Comma-separated list of `rules` that control how hostnames are mapped. +A comma-separated list of `rules` that control how hostnames are mapped. For example: @@ -60,7 +60,7 @@ For example: "www.google.com". These mappings apply to the endpoint host in a net request (the TCP connect -and host resolver in a direct connection, and the `CONNECT` in an http proxy +and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy connection, and the endpoint host in a `SOCKS` proxy connection). ## --host-resolver-rules=`rules` @@ -77,15 +77,15 @@ Ignores certificate related errors. ## --ppapi-flash-path=`path` -Sets `path` of pepper flash plugin. +Sets the `path` of the pepper flash plugin. ## --ppapi-flash-version=`version` -Sets `version` of pepper flash plugin. +Sets the `version` of the pepper flash plugin. ## --log-net-log=`path` -Enables saving net log events and writes them to `path`. +Enables net log events to be saved and writes them to `path`. ## --v=`log_level` @@ -102,7 +102,7 @@ source files `my_module.*` and `foo*.*`. Any pattern containing a forward or backward slash will be tested against the whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the -logging level for all code in source files under a `foo/bar` directory. +logging level for all code in the source files under a `foo/bar` directory. To disable all chromium related logs and only enable your application logs you can do: From 32b84bd3f9af942a1189ea0f3150898127771931 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 18:01:00 +0100 Subject: [PATCH 022/172] Improve grammar and punctuation of clipboard.md Improve the grammar, sentence structure, punctuation and formatting of `clipboard.md`. --- docs/api/clipboard.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index 572e91e96637..b2331b6279cc 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -1,14 +1,14 @@ # clipboard -The `clipboard` provides methods to do copy/paste operations. An example of -writing a string to clipboard: +The `clipboard` provides methods to perform copy and paste operations. The following example +shows how to write a string to the clipboard: ```javascript var clipboard = require('clipboard'); clipboard.writeText('Example String'); ``` -On X Window systems, there is also a selection clipboard, to manipulate in it +On X Window systems, there is also a selection clipboard. To manipulate it you need to pass `selection` to each method: ```javascript @@ -21,46 +21,46 @@ console.log(clipboard.readText('selection')); * `type` String -Returns the content in clipboard as plain text. +Returns the content in the clipboard as plain text. ## clipboard.writeText(text[, type]) * `text` String * `type` String -Writes the `text` into clipboard as plain text. +Writes the `text` into the clipboard as plain text. ## clipboard.readHtml([type]) * `type` String -Returns the content in clipboard as markup. +Returns the content in the clipboard as markup. ## clipboard.writeHtml(markup[, type]) * `markup` String * `type` String -Writes the `markup` into clipboard. +Writes `markup` into the clipboard. ## clipboard.readImage([type]) * `type` String -Returns the content in clipboard as [NativeImage](native-image.md). +Returns the content in the clipboard as a [NativeImage](native-image.md). ## clipboard.writeImage(image[, type]) * `image` [NativeImage](native-image.md) * `type` String -Writes the `image` into clipboard. +Writes `image` into the clipboard. ## clipboard.clear([type]) * `type` String -Clears everything in clipboard. +Clears the clipboard. ## clipboard.availableFormats([type]) @@ -71,7 +71,7 @@ Returns an array of supported `format` for the clipboard `type`. * `data` String * `type` String -Returns whether clipboard supports the format of specified `data`. +Returns whether the clipboard supports the format of specified `data`. ```javascript var clipboard = require('clipboard'); @@ -85,7 +85,7 @@ console.log(clipboard.has('

selection

')); * `data` String * `type` String -Reads the `data` in clipboard. +Reads `data` from the clipboard. **Note:** This API is experimental and could be removed in future. @@ -101,4 +101,4 @@ Reads the `data` in clipboard. var clipboard = require('clipboard'); clipboard.write({text: 'test', html: "test"}); ``` -Writes the `data` iinto clipboard. +Writes `data` into clipboard. From 8b4815fd95d862ee1e6fc8a3dc6f94044198ad2b Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 18:02:45 +0100 Subject: [PATCH 023/172] Improve grammar and punctuation of crash-reporter.md Improve the grammar, sentence structure, punctuation and formatting of `crash-reporter.md`. --- docs/api/crash-reporter.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index ec937e5252a5..da35008ea7f4 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -1,6 +1,6 @@ # crash-reporter -An example of automatically submitting crash reporters to a remote server: +The following is an example of automatically submitting a crash report to a remote server: ```javascript crashReporter = require('crash-reporter'); @@ -18,31 +18,30 @@ crashReporter.start({ * `productName` String, default: Electron * `companyName` String, default: GitHub, Inc * `submitUrl` String, default: http://54.249.141.255:1127/post - * URL that crash reports would be sent to as POST + * URL that crash reports will be sent to as POST * `autoSubmit` Boolean, default: true * Send the crash report without user interaction * `ignoreSystemCrashHandler` Boolean, default: false * `extra` Object - * An object you can define which content will be send along with the report. + * An object you can define that will be sent along with the report. * Only string properties are sent correctly. * Nested objects are not supported. -Developers are required to call this method before using other crashReporter APIs. +Developers are required to call this method before using other `crashReporter` APIs. - -**Note:** On OS X, electron uses a new `crashpad` client, which is different -with the `breakpad` on Windows and Linux. To enable crash collection feature, -you are required to call `crashReporter.start` API to initialize `crashpad` in -main process and in each renderer process that you wish to collect crash reports. +**Note:** On OS X, Electron uses a new `crashpad` client, which is different +from `breakpad` on Windows and Linux. To enable the crash collection feature, +you are required to call `crashReporter.start` API to initialize `crashpad` in the +main process and in each renderer process from which you wish to collect crash reports. ## crashReporter.getLastCrashReport() -Returns the date and ID of the last crash report, when there was no crash report -sent or the crash reporter is not started, `null` will be returned. +Returns the date and ID of the last crash report. If no crash reports have been +sent or the crash reporter has not been started, `null` is returned. ## crashReporter.getUploadedReports() -Returns all uploaded crash reports, each report contains date and uploaded ID. +Returns all uploaded crash reports. Each report contains the date and uploaded ID. # crash-reporter payload @@ -54,8 +53,8 @@ The crash reporter will send the following data to the `submitUrl` as `POST`: * `process_type` String - e.g. 'renderer' * `ptime` Number * `_version` String - The version in `package.json` -* `_productName` String - The product name in the crashReporter `options` object +* `_productName` String - The product name in the `crashReporter` `options` object * `prod` String - Name of the underlying product. In this case Electron -* `_companyName` String - The company name in the crashReporter `options` object +* `_companyName` String - The company name in the `crashReporter` `options` object * `upload_file_minidump` File - The crashreport as file -* All level one properties of the `extra` object in the crashReporter `options` object +* All level one properties of the `extra` object in the `crashReporter` `options` object From 8960aa956c669654c08c8a0727695ea81d1819e2 Mon Sep 17 00:00:00 2001 From: Yifei Teng Date: Thu, 23 Jul 2015 12:30:07 -0700 Subject: [PATCH 024/172] Only allow extensions explicitly specified by the user. Fixes #2296 --- atom/browser/ui/file_dialog_mac.mm | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index 9cd6c0380be6..96d230b1a1ea 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -18,25 +18,11 @@ namespace file_dialog { namespace { -CFStringRef CreateUTIFromExtension(const std::string& ext) { - base::ScopedCFTypeRef ext_cf(base::SysUTF8ToCFStringRef(ext)); - return UTTypeCreatePreferredIdentifierForTag( - kUTTagClassFilenameExtension, ext_cf.get(), NULL); -} - void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) { NSMutableSet* file_type_set = [NSMutableSet set]; for (size_t i = 0; i < filters.size(); ++i) { const Filter& filter = filters[i]; for (size_t j = 0; j < filter.second.size(); ++j) { - base::ScopedCFTypeRef uti( - CreateUTIFromExtension(filter.second[j])); - [file_type_set addObject:base::mac::CFToNSCast(uti.get())]; - - // Always allow the extension itself, in case the UTI doesn't map - // back to the original extension correctly. This occurs with dynamic - // UTIs on 10.7 and 10.8. - // See http://crbug.com/148840, http://openradar.me/12316273 base::ScopedCFTypeRef ext_cf( base::SysUTF8ToCFStringRef(filter.second[j])); [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; From d9ee8519e9d2da28673d74e877833d081e2ad094 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Thu, 23 Jul 2015 20:45:08 +0100 Subject: [PATCH 025/172] Correct error in chrome-command-line-switches.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace “to” with “in” to correct the error identified in `chrome-command-line-switches.md` by @OlsonDev. --- docs/api/chrome-command-line-switches.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 94bb200168ff..2f995c99b219 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -2,7 +2,7 @@ This page lists the command line switches used by the Chrome browser that are also supported by Electron. You can use [app.commandLine.appendSwitch][append-switch] to append -them to your app's main script before the [ready][ready] event of [app][app] +them in your app's main script before the [ready][ready] event of [app][app] module is emitted: ```javascript From 959f5d61b79007e213bf3b838574e40ebcfb98f7 Mon Sep 17 00:00:00 2001 From: Craig Shoemaker Date: Thu, 23 Jul 2015 15:04:43 -0700 Subject: [PATCH 026/172] Windows/Linux compatibility changes - Updated accelerator to cross platform values - Added a warning to non-Mac users regarding the selector option --- docs/api/menu.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index db149a29680a..41779ee63bee 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -29,6 +29,8 @@ window.addEventListener('contextmenu', function (e) { Another example of creating the application menu with the simple template API: +**Note to Window and Linux users** the `selector` member of each menu item is a Mac-only [Accellerator option](https://github.com/atom/electron/blob/master/docs/api/accelerator.md). + ```html + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index b47c72ac0fb8..55bbdbb01e65 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -228,3 +228,24 @@ describe ' tag', -> webview.setAttribute 'nodeintegration', 'on' webview.src = "file://#{fixtures}/pages/history.html" document.body.appendChild webview + + describe 'basic auth', -> + auth = require 'basic-auth' + + it 'should authenticate with correct credentials', (done) -> + message = 'Authenticated' + server = require('http').createServer (req, res) -> + credentials = auth(req) + if credentials.name == 'test' and credentials.pass == 'test' + res.end(message) + else + res.end('failed') + server.close() + server.listen 0, '127.0.0.1', -> + {port} = server.address() + webview.addEventListener 'ipc-message', (e) -> + assert.equal e.channel, message + done() + webview.src = "file://#{fixtures}/pages/basic-auth.html?port=#{port}" + webview.setAttribute 'nodeintegration', 'on' + document.body.appendChild webview From b52c07f65024d0cc5c6b3202b713115d0d5dfa89 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 24 Jul 2015 15:48:13 +0800 Subject: [PATCH 032/172] spec: Make dom-ready spec stronger --- docs/api/web-view-tag.md | 4 ++-- spec/api-browser-window-spec.coffee | 22 ---------------------- spec/fixtures/pages/dom-ready.html | 9 +++++++++ spec/fixtures/pages/f.html | 11 ----------- spec/webview-spec.coffee | 14 +++++++++++++- 5 files changed, 24 insertions(+), 36 deletions(-) create mode 100644 spec/fixtures/pages/dom-ready.html delete mode 100644 spec/fixtures/pages/f.html diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 973b62f5b767..0ff54c161704 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -130,10 +130,10 @@ If "on", the guest page will have web security disabled. ## Methods -The webview element must be loaded before using the methods. +The webview element must be loaded before using the methods. **Example** ```javascript -webview.addEventListener("dom-ready", function(){ +webview.addEventListener("dom-ready", function() { webview.openDevTools(); }); ``` diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index a2f4a66769e3..1b5705016831 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -257,25 +257,3 @@ describe 'browser-window module', -> assert.equal url, 'https://www.github.com/' done() w.loadUrl "file://#{fixtures}/pages/will-navigate.html" - - describe 'dom-ready event', -> - return if isCI and process.platform is 'darwin' - it 'emits when document is loaded', (done) -> - ipc = remote.require 'ipc' - server = http.createServer (req, res) -> - action = url.parse(req.url, true).pathname - if action == '/logo.png' - img = fs.readFileSync(path.join(fixtures, 'assets', 'logo.png')) - res.writeHead(200, {'Content-Type': 'image/png'}) - setTimeout -> - res.end(img, 'binary') - , 2000 - server.close() - server.listen 62542, '127.0.0.1' - ipc.on 'dom-ready', (e, state) -> - ipc.removeAllListeners 'dom-ready' - assert.equal state, 'interactive' - done() - w.webContents.on 'did-finish-load', -> - w.close() - w.loadUrl "file://#{fixtures}/pages/f.html" diff --git a/spec/fixtures/pages/dom-ready.html b/spec/fixtures/pages/dom-ready.html new file mode 100644 index 000000000000..541852f9ab0c --- /dev/null +++ b/spec/fixtures/pages/dom-ready.html @@ -0,0 +1,9 @@ + + + + + + diff --git a/spec/fixtures/pages/f.html b/spec/fixtures/pages/f.html deleted file mode 100644 index e2003a3ab0d8..000000000000 --- a/spec/fixtures/pages/f.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 55bbdbb01e65..7ab8969e7719 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -1,5 +1,6 @@ assert = require 'assert' path = require 'path' +http = require 'http' describe ' tag', -> fixtures = path.join __dirname, 'fixtures' @@ -234,7 +235,7 @@ describe ' tag', -> it 'should authenticate with correct credentials', (done) -> message = 'Authenticated' - server = require('http').createServer (req, res) -> + server = http.createServer (req, res) -> credentials = auth(req) if credentials.name == 'test' and credentials.pass == 'test' res.end(message) @@ -249,3 +250,14 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/basic-auth.html?port=#{port}" webview.setAttribute 'nodeintegration', 'on' document.body.appendChild webview + + describe 'dom-ready event', -> + it 'emits when document is loaded', (done) -> + server = http.createServer (req) -> + # Never respond, so the page never finished loading. + server.listen 0, '127.0.0.1', -> + {port} = server.address() + webview.addEventListener 'dom-ready', -> + done() + webview.src = "file://#{fixtures}/pages/dom-ready.html?port=#{port}" + document.body.appendChild webview From 417e97eef0338546c23216f4117f48671e50f102 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 24 Jul 2015 15:49:19 +0800 Subject: [PATCH 033/172] spec: Don't reuse port in session spec --- spec/api-session-spec.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index bd7c9bde5923..34a08ee50f09 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -20,8 +20,7 @@ describe 'session module', -> res.end('finished') server.close() - port = remote.process.port - server.listen port, '127.0.0.1', -> + server.listen 0, '127.0.0.1', -> {port} = server.address() w.loadUrl "#{url}:#{port}" w.webContents.on 'did-finish-load', -> From 73ded9d37830c4f947de4f8b4d91100558e4374e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 24 Jul 2015 16:04:54 +0800 Subject: [PATCH 034/172] linux: Fix min/max size not working --- atom/browser/native_window_views.cc | 19 ++---------- atom/browser/ui/views/native_frame_view.cc | 35 ++++++++++++++++++++++ atom/browser/ui/views/native_frame_view.h | 34 +++++++++++++++++++++ filenames.gypi | 2 ++ 4 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 atom/browser/ui/views/native_frame_view.cc create mode 100644 atom/browser/ui/views/native_frame_view.h diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 9613a3955f94..dbd8bf26ce3d 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -36,6 +36,7 @@ #include "atom/browser/browser.h" #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/window_state_watcher.h" #include "atom/browser/ui/x/x_window_utils.h" #include "base/environment.h" @@ -491,14 +492,6 @@ gfx::Size NativeWindowViews::GetContentSize() { void NativeWindowViews::SetMinimumSize(const gfx::Size& size) { minimum_size_ = size; - -#if defined(USE_X11) - XSizeHints size_hints; - size_hints.flags = PMinSize; - size_hints.min_width = size.width(); - size_hints.min_height = size.height(); - XSetWMNormalHints(gfx::GetXDisplay(), GetAcceleratedWidget(), &size_hints); -#endif } gfx::Size NativeWindowViews::GetMinimumSize() { @@ -507,14 +500,6 @@ gfx::Size NativeWindowViews::GetMinimumSize() { void NativeWindowViews::SetMaximumSize(const gfx::Size& size) { maximum_size_ = size; - -#if defined(USE_X11) - XSizeHints size_hints; - size_hints.flags = PMaxSize; - size_hints.max_width = size.width(); - size_hints.max_height = size.height(); - XSetWMNormalHints(gfx::GetXDisplay(), GetAcceleratedWidget(), &size_hints); -#endif } gfx::Size NativeWindowViews::GetMaximumSize() { @@ -899,7 +884,7 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView( return frame_view; #else if (has_frame_) { - return new views::NativeFrameView(widget); + return new NativeFrameView(this, widget); } else { FramelessView* frame_view = new FramelessView; frame_view->Init(this, widget); diff --git a/atom/browser/ui/views/native_frame_view.cc b/atom/browser/ui/views/native_frame_view.cc new file mode 100644 index 000000000000..a434fb434961 --- /dev/null +++ b/atom/browser/ui/views/native_frame_view.cc @@ -0,0 +1,35 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/views/native_frame_view.h" + +#include "atom/browser/native_window_views.h" + +namespace atom { + +namespace { + +const char kViewClassName[] = "AtomNativeFrameView"; + +} // namespace + +NativeFrameView::NativeFrameView(NativeWindowViews* window, + views::Widget* widget) + : views::NativeFrameView(widget), + window_(window) { +} + +gfx::Size NativeFrameView::GetMinimumSize() const { + return window_->GetMinimumSize(); +} + +gfx::Size NativeFrameView::GetMaximumSize() const { + return window_->GetMaximumSize(); +} + +const char* NativeFrameView::GetClassName() const { + return kViewClassName; +} + +} // namespace atom diff --git a/atom/browser/ui/views/native_frame_view.h b/atom/browser/ui/views/native_frame_view.h new file mode 100644 index 000000000000..acbe9cddc8dc --- /dev/null +++ b/atom/browser/ui/views/native_frame_view.h @@ -0,0 +1,34 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_H_ +#define ATOM_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_H_ + +#include "ui/views/window/native_frame_view.h" + +namespace atom { + +class NativeWindowViews; + +// Like the views::NativeFrameView, but returns the min/max size from the +// NativeWindowViews. +class NativeFrameView : public views::NativeFrameView { + public: + NativeFrameView(NativeWindowViews* window, views::Widget* widget); + + protected: + // views::View: + gfx::Size GetMinimumSize() const override; + gfx::Size GetMaximumSize() const override; + const char* GetClassName() const override; + + private: + NativeWindowViews* window_; // weak ref. + + DISALLOW_COPY_AND_ASSIGN(NativeFrameView); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_H_ diff --git a/filenames.gypi b/filenames.gypi index 837dd3301cc8..ed51fc8fb47b 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -196,6 +196,8 @@ 'atom/browser/ui/views/menu_delegate.h', 'atom/browser/ui/views/menu_layout.cc', 'atom/browser/ui/views/menu_layout.h', + 'atom/browser/ui/views/native_frame_view.cc', + 'atom/browser/ui/views/native_frame_view.h', 'atom/browser/ui/views/submenu_button.cc', 'atom/browser/ui/views/submenu_button.h', 'atom/browser/ui/views/win_frame_view.cc', From 7ceca9f4269929b5a1c5e98e82a42b72e08f919e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 24 Jul 2015 16:59:18 +0800 Subject: [PATCH 035/172] Bump v0.30.1 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index d8da82cd548f..bf67c767c17f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.30.0', + 'version%': '0.30.1', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 68ce951ed4d4..28d56286e968 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.30.0 + 0.30.1 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 80714c55fd25..3485ad963c39 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,30,0,0 - PRODUCTVERSION 0,30,0,0 + FILEVERSION 0,30,1,0 + PRODUCTVERSION 0,30,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.30.0" + VALUE "FileVersion", "0.30.1" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.30.0" + VALUE "ProductVersion", "0.30.1" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 64d0c7bfd73d..0240a423bc4f 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 30 -#define ATOM_PATCH_VERSION 0 +#define ATOM_PATCH_VERSION 1 #define ATOM_VERSION_IS_RELEASE 1 From 08383a69cea60db3d87fbe9842d21ffe0c4ef753 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 24 Jul 2015 03:10:03 -0700 Subject: [PATCH 036/172] Propagate User App Model ID to Tray Icon This PR prevents dozens of items showing up in the notification area preferences when using Squirrel for Windows, by ensuring that notification tray items are tied to the User App Model ID. --- atom/browser/ui/win/notify_icon.cc | 16 ++++++++++++++++ atom/browser/ui/win/notify_icon.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index bc9ff46f939a..6f75bb311dae 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -4,7 +4,10 @@ #include "atom/browser/ui/win/notify_icon.h" +#include + #include "atom/browser/ui/win/notify_icon_host.h" +#include "base/md5.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/win/windows_version.h" @@ -26,6 +29,18 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, window_(window), message_id_(message), menu_model_(NULL) { + + // NB: If we have an App Model ID, we should propagate that to the tray. + // Doing this prevents duplicate items from showing up in the notification + // preferences (i.e. "Always Show / Show notifications only / etc") + PWSTR explicit_app_id; + + if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) { + // GUIDs and MD5 hashes are the same length. So convenient! + MD5Sum(explicit_app_id, sizeof(wchar_t) * wcslen(explicit_app_id), (MD5Digest*)&tray_app_id_hash_); + CoTaskMemFree(explicit_app_id); + } + NOTIFYICONDATA icon_data; InitIconData(&icon_data); icon_data.uFlags = NIF_MESSAGE; @@ -161,6 +176,7 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) { icon_data->cbSize = sizeof(NOTIFYICONDATA); icon_data->hWnd = window_; icon_data->uID = icon_id_; + memcpy(icon_data->guidItem, tray_app_id_hash_, sizeof(GUID)); } } // namespace atom diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 8e00f1267920..56b4b4f09be8 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -75,6 +75,9 @@ class NotifyIcon : public TrayIcon { // The context menu. ui::SimpleMenuModel* menu_model_; + + // A hash of the app model ID + GUID tray_app_id_hash_; DISALLOW_COPY_AND_ASSIGN(NotifyIcon); }; From 75b08f510ee021b3a984095dce873769ae127fb8 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 24 Jul 2015 03:27:15 -0700 Subject: [PATCH 037/172] Fix up namespaces --- atom/browser/ui/win/notify_icon.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 6f75bb311dae..e9b153b49ab6 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -29,18 +29,21 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, window_(window), message_id_(message), menu_model_(NULL) { - - // NB: If we have an App Model ID, we should propagate that to the tray. + + // NB: If we have an App Model ID, we should propagate that to the tray. // Doing this prevents duplicate items from showing up in the notification // preferences (i.e. "Always Show / Show notifications only / etc") PWSTR explicit_app_id; - + if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) { // GUIDs and MD5 hashes are the same length. So convenient! - MD5Sum(explicit_app_id, sizeof(wchar_t) * wcslen(explicit_app_id), (MD5Digest*)&tray_app_id_hash_); + base::MD5Sum(explicit_app_id, + sizeof(wchar_t) * wcslen(explicit_app_id), + (base::MD5Digest*)&tray_app_id_hash_); + CoTaskMemFree(explicit_app_id); } - + NOTIFYICONDATA icon_data; InitIconData(&icon_data); icon_data.uFlags = NIF_MESSAGE; @@ -176,7 +179,7 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) { icon_data->cbSize = sizeof(NOTIFYICONDATA); icon_data->hWnd = window_; icon_data->uID = icon_id_; - memcpy(icon_data->guidItem, tray_app_id_hash_, sizeof(GUID)); + memcpy((void*)&icon_data->guidItem, &tray_app_id_hash_, sizeof(GUID)); } } // namespace atom From 70feb08f8495eabbb44c3fae3064aaa5c836638e Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 24 Jul 2015 03:30:23 -0700 Subject: [PATCH 038/172] Fix linting issues --- atom/browser/ui/win/notify_icon.cc | 7 +++++-- atom/browser/ui/win/notify_icon.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index e9b153b49ab6..787982d04dbf 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -40,7 +40,7 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, base::MD5Sum(explicit_app_id, sizeof(wchar_t) * wcslen(explicit_app_id), (base::MD5Digest*)&tray_app_id_hash_); - + CoTaskMemFree(explicit_app_id); } @@ -179,7 +179,10 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) { icon_data->cbSize = sizeof(NOTIFYICONDATA); icon_data->hWnd = window_; icon_data->uID = icon_id_; - memcpy((void*)&icon_data->guidItem, &tray_app_id_hash_, sizeof(GUID)); + + memcpy(reinterpret_cast(&icon_data->guidItem), + &tray_app_id_hash_, + sizeof(GUID)); } } // namespace atom diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 56b4b4f09be8..a52388d56298 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -75,7 +75,7 @@ class NotifyIcon : public TrayIcon { // The context menu. ui::SimpleMenuModel* menu_model_; - + // A hash of the app model ID GUID tray_app_id_hash_; From d485cfbca31a30de1f361d6aaa4148181defc9bf Mon Sep 17 00:00:00 2001 From: Craig Shoemaker Date: Fri, 24 Jul 2015 06:53:55 -0700 Subject: [PATCH 039/172] Fixed typo --- docs/api/menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 41779ee63bee..06400d116917 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -29,7 +29,7 @@ window.addEventListener('contextmenu', function (e) { Another example of creating the application menu with the simple template API: -**Note to Window and Linux users** the `selector` member of each menu item is a Mac-only [Accellerator option](https://github.com/atom/electron/blob/master/docs/api/accelerator.md). +**Note to Window and Linux users** the `selector` member of each menu item is a Mac-only [Accelerator option](https://github.com/atom/electron/blob/master/docs/api/accelerator.md). ```html From 5e61974c24c90ebc81562a2f1259ae018db0aab0 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 24 Jul 2015 08:02:14 -0700 Subject: [PATCH 040/172] Set NIF_GUID if we have a GUID --- atom/browser/ui/win/notify_icon.cc | 20 ++++++++++++-------- atom/browser/ui/win/notify_icon.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 787982d04dbf..6cf207d7b8e1 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -40,13 +40,14 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, base::MD5Sum(explicit_app_id, sizeof(wchar_t) * wcslen(explicit_app_id), (base::MD5Digest*)&tray_app_id_hash_); + has_tray_app_id_hash_ = true; CoTaskMemFree(explicit_app_id); } NOTIFYICONDATA icon_data; InitIconData(&icon_data); - icon_data.uFlags = NIF_MESSAGE; + icon_data.uFlags |= NIF_MESSAGE; icon_data.uCallbackMessage = message_id_; BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data); // This can happen if the explorer process isn't running when we try to @@ -89,7 +90,7 @@ void NotifyIcon::ResetIcon() { // Delete any previously existing icon. Shell_NotifyIcon(NIM_DELETE, &icon_data); InitIconData(&icon_data); - icon_data.uFlags = NIF_MESSAGE; + icon_data.uFlags |= NIF_MESSAGE; icon_data.uCallbackMessage = message_id_; icon_data.hIcon = icon_.Get(); // If we have an image, then set the NIF_ICON flag, which tells @@ -106,7 +107,7 @@ void NotifyIcon::SetImage(const gfx::Image& image) { // Create the icon. NOTIFYICONDATA icon_data; InitIconData(&icon_data); - icon_data.uFlags = NIF_ICON; + icon_data.uFlags |= NIF_ICON; icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap())); icon_data.hIcon = icon_.Get(); BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); @@ -123,7 +124,7 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) { // Create the icon. NOTIFYICONDATA icon_data; InitIconData(&icon_data); - icon_data.uFlags = NIF_TIP; + icon_data.uFlags |= NIF_TIP; wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str()); BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); if (!result) @@ -135,7 +136,7 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, const base::string16& contents) { NOTIFYICONDATA icon_data; InitIconData(&icon_data); - icon_data.uFlags = NIF_INFO; + icon_data.uFlags |= NIF_INFO; icon_data.dwInfoFlags = NIIF_INFO; wcscpy_s(icon_data.szInfoTitle, title.c_str()); wcscpy_s(icon_data.szInfo, contents.c_str()); @@ -180,9 +181,12 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) { icon_data->hWnd = window_; icon_data->uID = icon_id_; - memcpy(reinterpret_cast(&icon_data->guidItem), - &tray_app_id_hash_, - sizeof(GUID)); + if (has_tray_app_id_hash_) { + icon_data->uFlags |= NIF_GUID; + memcpy(reinterpret_cast(&icon_data->guidItem), + &tray_app_id_hash_, + sizeof(GUID)); + } } } // namespace atom diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index a52388d56298..25ba8c8dc439 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -78,6 +78,7 @@ class NotifyIcon : public TrayIcon { // A hash of the app model ID GUID tray_app_id_hash_; + bool has_tray_app_id_hash_; DISALLOW_COPY_AND_ASSIGN(NotifyIcon); }; From 9eeebedf5fcde6de4289aba6bc84f04dab4bb640 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 11:43:23 +0800 Subject: [PATCH 041/172] Add pageSize option in printToPDF API. --- atom/browser/api/lib/web-contents.coffee | 80 ++++++++++++++++-------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index b2232b72cda6..cb6cc7c0b3d8 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -6,6 +6,34 @@ ipc = require 'ipc' nextId = 0 getNextId = -> ++nextId +PDFPageSize = + A4: + custom_display_name: "A4" + height_microns: 297000 + name: "ISO_A4" + is_default: "true" + width_microns: 210000 + A3: + custom_display_name: "A3" + height_microns: 420000 + name: "ISO_A3" + width_microns: 297000 + Legal: + custom_display_name: "Legal" + height_microns: 355600 + name: "NA_LEGAL" + width_microns: 215900 + Letter: + custom_display_name: "Letter" + height_microns: 279400 + name: "NA_LETTER" + width_microns: 215900 + Tabloid: + height_microns: 431800 + name: "NA_LEDGER" + width_microns: 279400 + custom_display_name: "Tabloid" + wrapWebContents = (webContents) -> # webContents is an EventEmitter. webContents.__proto__ = EventEmitter.prototype @@ -41,32 +69,27 @@ wrapWebContents = (webContents) -> webContents.printToPDF = (options, callback) -> printingSetting = - pageRage:[], - mediaSize: - height_microns:297000, - is_default:true, - name:"ISO_A4", - width_microns:210000, - custom_display_name:"A4", - landscape:false, - color:2, - headerFooterEnabled:false, - marginsType:0, - isFirstRequest:false, - requestID: getNextId(), - previewModifiable:true, - printToPDF:true, - printWithCloudPrint:false, - printWithPrivet:false, - printWithExtension:false, - deviceName:"Save as PDF", - generateDraftData:true, - fitToPageEnabled:false, - duplex:0, - copies:1, - collate:true, - shouldPrintBackgrounds:false, - shouldPrintSelectionOnly:false + pageRage: [] + mediaSize: {} + landscape: false + color: 2 + headerFooterEnabled: false + marginsType: 0 + isFirstRequest: false + requestID: getNextId() + previewModifiable: true + printToPDF: true + printWithCloudPrint: false + printWithPrivet: false + printWithExtension: false + deviceName: "Save as PDF" + generateDraftData: true + fitToPageEnabled: false + duplex: 0 + copies: 1 + collate: true + shouldPrintBackgrounds: false + shouldPrintSelectionOnly: false if options.landscape printingSetting.landscape = options.landscape @@ -77,6 +100,11 @@ wrapWebContents = (webContents) -> if options.printBackgrounds printingSetting.shouldPrintBackgrounds = options.printBackground + if options.pageSize and PDFPageSize[options.pageSize] + printingSetting.mediaSize = PDFPageSize[options.pageSize] + else + printingSetting.mediaSize = PDFPageSize['A4'] + @_printToPDF printingSetting, callback binding._setWrapWebContents wrapWebContents From f53995d5550db47f05db28afff9694f782996303 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Sat, 25 Jul 2015 20:56:35 -0700 Subject: [PATCH 042/172] Send bounding Rect on tray double click events --- atom/browser/api/atom_api_tray.cc | 4 ++-- atom/browser/api/atom_api_tray.h | 2 +- atom/browser/ui/tray_icon.cc | 4 ++-- atom/browser/ui/tray_icon.h | 2 +- atom/browser/ui/tray_icon_cocoa.mm | 2 +- atom/browser/ui/tray_icon_observer.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index a209537c940f..82b2d01c613b 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -44,8 +44,8 @@ void Tray::OnClicked(const gfx::Rect& bounds) { Emit("clicked", bounds); } -void Tray::OnDoubleClicked() { - Emit("double-clicked"); +void Tray::OnDoubleClicked(const gfx::Rect& bounds) { + Emit("double-clicked", bounds); } void Tray::OnBalloonShow() { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 10ea3836819e..f3b91f00c0f0 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -43,7 +43,7 @@ class Tray : public mate::EventEmitter, // TrayIconObserver: void OnClicked(const gfx::Rect& bounds) override; - void OnDoubleClicked() override; + void OnDoubleClicked(const gfx::Rect& bounds) override; void OnBalloonShow() override; void OnBalloonClicked() override; void OnBalloonClosed() override; diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index 456cbe47a5a3..b22250d35c8f 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -33,8 +33,8 @@ void TrayIcon::NotifyClicked(const gfx::Rect& bounds) { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(bounds)); } -void TrayIcon::NotifyDoubleClicked() { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDoubleClicked()); +void TrayIcon::NotifyDoubleClicked(const gfx::Rect& bounds) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDoubleClicked(bounds)); } void TrayIcon::NotifyBalloonShow() { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index d6885699d01d..5e362806f5d6 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -55,7 +55,7 @@ class TrayIcon { void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); } void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); } void NotifyClicked(const gfx::Rect& = gfx::Rect()); - void NotifyDoubleClicked(); + void NotifyDoubleClicked(const gfx::Rect& = gfx::Rect()); void NotifyBalloonShow(); void NotifyBalloonClicked(); void NotifyBalloonClosed(); diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index fddbd8c16eb0..59386ff8eb41 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -156,7 +156,7 @@ const CGFloat kMargin = 3; } if (event.clickCount == 2 && !menuController_) { - trayIcon_->NotifyDoubleClicked(); + trayIcon_->NotifyDoubleClicked([self getBoundsFromEvent:event]); } [self setNeedsDisplay:YES]; } diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index 6c9839a38a1f..474c6a771934 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -17,7 +17,7 @@ namespace atom { class TrayIconObserver { public: virtual void OnClicked(const gfx::Rect& bounds) {} - virtual void OnDoubleClicked() {} + virtual void OnDoubleClicked(const gfx::Rect& bounds) {} virtual void OnBalloonShow() {} virtual void OnBalloonClicked() {} virtual void OnBalloonClosed() {} From 74f2e9f102146e32b55d0c8a1ba4ee560fd6383e Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 11:56:07 +0800 Subject: [PATCH 043/172] :memo: pageSize option. --- docs/api/browser-window.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index c8fc39a53f1f..cee68183f783 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1001,6 +1001,12 @@ size. * 0 - default * 1 - none * 2 - minimum + * `pageSize` String - Specify page size of the generated PDF + * `A4` + * `A3` + * `Legal` + * `Letter` + * `Tabloid` * `printBackground` Boolean - Whether to print CSS backgrounds. * `printSelectionOnly` Boolean - Whether to print selection only. * `landscape` Boolean - `true` for landscape, `false` for portrait. @@ -1027,9 +1033,10 @@ win.webContents.on("did-finish-load", function() { // Use default printing options win.webContents.printToPDF({}, function(error, data) { if (error) throw error; - fs.writeFile(dist, data, function(error) { + fs.writeFile("/tmp/print.pdf", data, function(error) { if (err) - alert('write pdf file error', error); + throw error; + console.log("Write PDF successfully."); }) }) }); From 1a074bb14850604350de072b53354dd216080866 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Sat, 25 Jul 2015 21:16:15 -0700 Subject: [PATCH 044/172] Update tray double-click docs * Mention bounds payload --- docs/api/tray.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api/tray.md b/docs/api/tray.md index 847b0b2cf818..9332822a32a8 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -76,6 +76,13 @@ will be emitted if the tray icon has context menu. Emitted when the tray icon is double clicked. +* `event` +* `bounds` Object - the bounds of tray icon + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + __Note:__ This is only implemented on OS X. ### Event: 'balloon-show' From 0700f08d6da7c7c7cabb18a878a3fc63efdb2346 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 16:08:29 +0800 Subject: [PATCH 045/172] Copy pref_names files from Chromium. --- atom/browser/web_dialog_helper.cc | 7 +++---- chromium_src/chrome/common/pref_names.cc | 11 +++++++++++ chromium_src/chrome/common/pref_names.h | 11 +++++++++++ filenames.gypi | 2 ++ 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 chromium_src/chrome/common/pref_names.cc diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index 93cb32cba7c7..7b467cfcdfcb 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -15,6 +15,7 @@ #include "base/files/file_path.h" #include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/common/pref_names.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/file_chooser_file_info.h" @@ -23,8 +24,6 @@ namespace { -const char kSelectFileLastDirectory[] = "selectfile.last_directory"; - file_dialog::Filters GetFileTypesFromAcceptType( const std::vector& accept_types) { file_dialog::Filters filters; @@ -111,7 +110,7 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, AtomBrowserContext* browser_context = static_cast( window_->web_contents()->GetBrowserContext()); base::FilePath default_file_path = browser_context->prefs()->GetFilePath( - kSelectFileLastDirectory).Append(params.default_file_name); + prefs::kSelectFileLastDirectory).Append(params.default_file_name); if (file_dialog::ShowOpenDialog(window_, base::UTF16ToUTF8(params.title), default_file_path, @@ -125,7 +124,7 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents, result.push_back(info); } if (!paths.empty()) { - browser_context->prefs()->SetFilePath(kSelectFileLastDirectory, + browser_context->prefs()->SetFilePath(prefs::kSelectFileLastDirectory, paths[0].DirName()); } } diff --git a/chromium_src/chrome/common/pref_names.cc b/chromium_src/chrome/common/pref_names.cc new file mode 100644 index 000000000000..3871fde2c2f0 --- /dev/null +++ b/chromium_src/chrome/common/pref_names.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/pref_names.h" + +namespace prefs { + +const char kSelectFileLastDirectory[] = "selectfile.last_directory"; + +} // namespace prefs diff --git a/chromium_src/chrome/common/pref_names.h b/chromium_src/chrome/common/pref_names.h index e69de29bb2d1..78bd2a04800b 100644 --- a/chromium_src/chrome/common/pref_names.h +++ b/chromium_src/chrome/common/pref_names.h @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Constants for the names of various preferences, for easier changing. + +namespace prefs { + +extern const char kSelectFileLastDirectory[]; + +} // namespace prefs diff --git a/filenames.gypi b/filenames.gypi index ed51fc8fb47b..82f9ea95d078 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -364,6 +364,8 @@ 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h', 'chromium_src/chrome/common/chrome_utility_messages.h', + 'chromium_src/chrome/common/pref_names.cc', + 'chromium_src/chrome/common/pref_names.h', 'chromium_src/chrome/common/print_messages.cc', 'chromium_src/chrome/common/print_messages.h', 'chromium_src/chrome/common/tts_messages.h', From 2aa17debc8daa253eb81e0893f458125e5e324a1 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 16:17:55 +0800 Subject: [PATCH 046/172] prefs' key needs to be registered before using. --- atom/browser/atom_browser_context.cc | 8 ++++++++ atom/browser/atom_browser_context.h | 1 + 2 files changed, 9 insertions(+) diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 1874d5b03b19..65307d0ef7c1 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -15,10 +15,13 @@ #include "atom/common/chrome_version.h" #include "atom/common/options_switches.h" #include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/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/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/url_constants.h" #include "content/public/common/user_agent.h" @@ -146,4 +149,9 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { return guest_manager_.get(); } +void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { + pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, + base::FilePath()); +} + } // namespace atom diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 513cc86bca68..d64a894070f8 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -31,6 +31,7 @@ class AtomBrowserContext : public brightray::BrowserContext { // content::BrowserContext: content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; + void RegisterPrefs(PrefRegistrySimple* pref_registry) override; AtomURLRequestJobFactory* job_factory() const { return job_factory_; } From fef53d18c4b694799b775bb53a764d8c803ceb2b Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 16:30:02 +0800 Subject: [PATCH 047/172] Add `session.setDownloadPath` API. --- atom/browser/api/atom_api_session.cc | 11 ++++++++++- atom/browser/api/atom_api_session.h | 1 + atom/browser/atom_browser_context.cc | 2 ++ atom/browser/atom_download_manager_delegate.cc | 13 +++++++++++++ chromium_src/chrome/common/pref_names.cc | 1 + chromium_src/chrome/common/pref_names.h | 1 + 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 483b730d1c70..c864598a3191 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -10,8 +10,11 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/atom_browser_context.h" #include "atom/common/native_mate_converters/gurl_converter.h" -#include "base/thread_task_runner_handle.h" +#include "base/files/file_path.h" +#include "base/prefs/pref_service.h" #include "base/strings/string_util.h" +#include "base/thread_task_runner_handle.h" +#include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "native_mate/callback.h" @@ -251,6 +254,11 @@ void Session::SetProxy(const std::string& proxy, base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback)); } +void Session::SetDownloadPath(const std::string& path) { + browser_context_->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory, + base::FilePath(path)); +} + v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { auto handle = atom::api::Cookies::Create(isolate, browser_context_); @@ -266,6 +274,7 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( .SetMethod("clearCache", &Session::ClearCache) .SetMethod("clearStorageData", &Session::ClearStorageData) .SetMethod("setProxy", &Session::SetProxy) + .SetMethod("setDownloadPath", &Session::SetDownloadPath) .SetProperty("cookies", &Session::Cookies); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 3963ed21189a..a8c0e2444955 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -46,6 +46,7 @@ class Session: public mate::TrackableObject { void ClearCache(const net::CompletionCallback& callback); void ClearStorageData(mate::Arguments* args); void SetProxy(const std::string& proxy, const base::Closure& callback); + void SetDownloadPath(const std::string& path); v8::Local Cookies(v8::Isolate* isolate); v8::Global cookies_; diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 65307d0ef7c1..f04fbca747e6 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -152,6 +152,8 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, base::FilePath()); + pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory, + base::FilePath()); } } // namespace atom diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index 46c4af2dc387..7e393f7d2c21 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -6,10 +6,13 @@ #include +#include "atom/browser/atom_browser_context.h" #include "atom/browser/native_window.h" #include "atom/browser/ui/file_dialog.h" #include "base/bind.h" #include "base/files/file_util.h" +#include "base/prefs/pref_service.h" +#include "chrome/common/pref_names.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_manager.h" @@ -77,6 +80,11 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( return; } + // Remeber the last selected download directory. + AtomBrowserContext* browser_context = static_cast( + download_manager_->GetBrowserContext()); + browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory, + path.DirName()); callback.Run(path, content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path); @@ -92,6 +100,11 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget( const content::DownloadTargetCallback& callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + AtomBrowserContext* browser_context = static_cast( + download_manager_->GetBrowserContext()); + default_download_path_ = browser_context->prefs()->GetFilePath( + prefs::kDownloadDefaultDirectory); + // If users didn't set download path, use 'Downloads' directory by default. if (default_download_path_.empty()) { auto path = download_manager_->GetBrowserContext()->GetPath(); default_download_path_ = path.Append(FILE_PATH_LITERAL("Downloads")); diff --git a/chromium_src/chrome/common/pref_names.cc b/chromium_src/chrome/common/pref_names.cc index 3871fde2c2f0..3e3a73b99837 100644 --- a/chromium_src/chrome/common/pref_names.cc +++ b/chromium_src/chrome/common/pref_names.cc @@ -7,5 +7,6 @@ namespace prefs { const char kSelectFileLastDirectory[] = "selectfile.last_directory"; +const char kDownloadDefaultDirectory[] = "download.default_directory"; } // namespace prefs diff --git a/chromium_src/chrome/common/pref_names.h b/chromium_src/chrome/common/pref_names.h index 78bd2a04800b..542a2d2c733f 100644 --- a/chromium_src/chrome/common/pref_names.h +++ b/chromium_src/chrome/common/pref_names.h @@ -7,5 +7,6 @@ namespace prefs { extern const char kSelectFileLastDirectory[]; +extern const char kDownloadDefaultDirectory[]; } // namespace prefs From 7f0cb0ce1b00bc1122b4e6620fac9073693f517b Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 26 Jul 2015 16:52:02 +0800 Subject: [PATCH 048/172] :memo: session.setDownloadPath API. --- docs/api/browser-window.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index c8fc39a53f1f..766b9ce92439 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1220,3 +1220,7 @@ proxy-uri = ["://"][":"] and use socks4://foopy2 for all other URLs. ``` + +### Session.setDownloadPath(path) + +* `path` String - The download location From b0e73532de0330c6b67363b249e6ec6074d85f1c Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 27 Jul 2015 02:51:41 +0530 Subject: [PATCH 049/172] protocol: fix request headers in urlRequestFetchJob --- atom/browser/net/url_request_fetch_job.cc | 5 +---- spec/api-protocol-spec.coffee | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index 5389b8bb6216..abad38d7f4d5 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -107,10 +107,7 @@ URLRequestFetchJob::URLRequestFetchJob( } // Use |request|'s headers. - net::HttpRequestHeaders headers; - if (request->GetFullRequestHeaders(&headers)) { - fetcher_->SetExtraRequestHeaders(headers.ToString()); - } + fetcher_->SetExtraRequestHeaders(request->extra_request_headers().ToString()); } net::URLRequestContextGetter* URLRequestFetchJob::GetRequestContext() { diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index b65002a63189..4f2fb79da372 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -81,6 +81,7 @@ describe 'protocol module', -> it 'returns RequestHttpJob should send respone', (done) -> server = http.createServer (req, res) -> + assert.notEqual req.headers.accept, '' res.writeHead(200, {'Content-Type': 'text/plain'}) res.end('hello') server.close() From b6f6bf9778e1e49cb2e5192e7d6ddbd427b8ddf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Sun, 26 Jul 2015 20:26:10 -0400 Subject: [PATCH 050/172] :memo: Reorganize the Run Your App section --- docs/tutorial/quick-start.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ae60fb27ec71..ec3fba9bbfd1 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -130,24 +130,41 @@ Finally the `index.html` is the web page you want to show: ## Run your app -After you're done writing your app, you can create a distribution by -following the [Application distribution](./application-distribution.md) guide -and then execute the packaged app. You can also just use the downloaded -Electron binary to execute your app directly. +Once you've created your initial `main.js`, `index.html`, and `package.json` files, +you'll probably want to try running your app locally to test it and make sure it's +working as expected. -On Windows: +### electron-prebuilt +If you've installed `electron-prebuilt` globally with `npm`, then you need only +run the following in your app's source directory: + +```bash +electron . +``` + +If you've installed it locally, then run: + +```bash +./node_modules/.bin/electron . +``` + +### Manually Downloaded Electron Binary +If you downloaded Electron manually, you can also just use the included +binary to execute your app directly. + +#### Windows ```bash $ .\electron\electron.exe your-app\ ``` -On Linux: +#### Linux ```bash $ ./electron/electron your-app/ ``` -On OS X: +#### OS X ```bash $ ./Electron.app/Contents/MacOS/Electron your-app/ @@ -155,3 +172,8 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ `Electron.app` here is part of the Electron's release package, you can download it from [here](https://github.com/atom/electron/releases). + +### Run as a distribution +After you're done writing your app, you can create a distribution by +following the [Application distribution](./application-distribution.md) guide +and then execute the packaged app. From f2b2c58758464d1aece8340e694f7416a425b2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Sun, 26 Jul 2015 20:31:01 -0400 Subject: [PATCH 051/172] :memo: :art: Grammar fix --- docs/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ec3fba9bbfd1..197cf0d3b32b 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -176,4 +176,4 @@ it from [here](https://github.com/atom/electron/releases). ### Run as a distribution After you're done writing your app, you can create a distribution by following the [Application distribution](./application-distribution.md) guide -and then execute the packaged app. +and then executing the packaged app. From 59c3efd44bbbcc1523bdf4f7715b30ecddc4aa84 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 27 Jul 2015 09:09:32 +0800 Subject: [PATCH 052/172] Correct the override comment. --- atom/browser/atom_browser_context.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index d64a894070f8..3455916fa5b3 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -31,6 +31,8 @@ class AtomBrowserContext : public brightray::BrowserContext { // content::BrowserContext: content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; + + // brightray::BrowserContext:: void RegisterPrefs(PrefRegistrySimple* pref_registry) override; AtomURLRequestJobFactory* job_factory() const { return job_factory_; } From faf10183d8275daedb23659641135e236418c973 Mon Sep 17 00:00:00 2001 From: Matias Insaurralde Date: Sun, 26 Jul 2015 22:57:43 -0400 Subject: [PATCH 053/172] first docs --- docs/README-es.md | 34 ++-- docs/tutorial/application-distribution-es.md | 114 ++++++++++++ docs/tutorial/application-packaging-es.md | 157 ++++++++++++++++ docs/tutorial/debugging-main-process-es.md | 45 +++++ .../desktop-environment-integration-es.md | 171 ++++++++++++++++++ docs/tutorial/devtools-extension-es.md | 49 +++++ docs/tutorial/online-offline-events-es.md | 80 ++++++++ docs/tutorial/quick-start-es.md | 154 ++++++++++++++++ docs/tutorial/using-native-node-modules-es.md | 57 ++++++ docs/tutorial/using-pepper-flash-plugin-es.md | 58 ++++++ .../using-selenium-and-webdriver-es.md | 72 ++++++++ 11 files changed, 974 insertions(+), 17 deletions(-) create mode 100644 docs/tutorial/application-distribution-es.md create mode 100644 docs/tutorial/application-packaging-es.md create mode 100644 docs/tutorial/debugging-main-process-es.md create mode 100644 docs/tutorial/desktop-environment-integration-es.md create mode 100644 docs/tutorial/devtools-extension-es.md create mode 100644 docs/tutorial/online-offline-events-es.md create mode 100644 docs/tutorial/quick-start-es.md create mode 100644 docs/tutorial/using-native-node-modules-es.md create mode 100644 docs/tutorial/using-pepper-flash-plugin-es.md create mode 100644 docs/tutorial/using-selenium-and-webdriver-es.md diff --git a/docs/README-es.md b/docs/README-es.md index 16ecc3afd4b3..991c80b069f3 100644 --- a/docs/README-es.md +++ b/docs/README-es.md @@ -1,16 +1,16 @@ ## Guías -* [Application distribution](tutorial/application-distribution.md) -* [Application packaging](tutorial/application-packaging.md) -* [Utilizando módulos nativos](tutorial/using-native-node-modules.md) -* [Depurando el proceso principal](tutorial/debugging-main-process.md) -* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver.md) -* [Extensión DevTools](tutorial/devtools-extension.md) -* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin.md) +* [Distribución de aplicaciones](tutorial/application-distribution-es.md) +* [Empaquetamiento de aplicaciones](tutorial/application-packaging-es.md) +* [Utilizando módulos nativos](tutorial/using-native-node-modules-es.md) +* [Depurando el proceso principal](tutorial/debugging-main-process-es.md) +* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver-es.md) +* [Extensión DevTools](tutorial/devtools-extension-es.md) +* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin-es.md) ## Tutoriales -* [Quick start](tutorial/quick-start.md) +* [Introducción](tutorial/quick-start.md) * [Integración con el entorno de escritorio](tutorial/desktop-environment-integration.md) * [Detección del evento en línea/fuera de línea](tutorial/online-offline-events.md) @@ -18,7 +18,7 @@ * [Sinopsis](api/synopsis.md) * [Proceso](api/process.md) -* [Supported Chrome command line switches](api/chrome-command-line-switches.md) +* [Parámetros CLI soportados (Chrome)](api/chrome-command-line-switches.md) Elementos DOM customizados: @@ -26,7 +26,7 @@ Elementos DOM customizados: * [`` tag](api/web-view-tag.md) * [`window.open` function](api/window-open.md) -Módulos para el proceso principal: +Módulos del proceso principal: * [app](api/app.md) * [auto-updater](api/auto-updater.md) @@ -42,13 +42,13 @@ Módulos para el proceso principal: * [protocol](api/protocol.md) * [tray](api/tray.md) -Módulos para el renderer (página web): +Módulos del renderer (página web): * [ipc (renderer)](api/ipc-renderer.md) * [remote](api/remote.md) * [web-frame](api/web-frame.md) -Módulos para ambos procesos: +Módulos de ambos procesos: * [clipboard](api/clipboard.md) * [crash-reporter](api/crash-reporter.md) @@ -61,8 +61,8 @@ Módulos para ambos procesos: * [Guía de estilo](development/coding-style.md) * [Estructura de directorio](development/source-code-directory-structure.md) * [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) -* [Build system overview](development/build-system-overview.md) -* [Build instructions (Mac)](development/build-instructions-mac.md) -* [Build instructions (Windows)](development/build-instructions-windows.md) -* [Build instructions (Linux)](development/build-instructions-linux.md) -* [Setting up symbol server in debugger](development/setting-up-symbol-server.md) +* [Sistema de compilación](development/build-system-overview.md) +* [Instrucciones de compilación (Mac)](development/build-instructions-mac.md) +* [Instrucciones de compilación (Windows)](development/build-instructions-windows.md) +* [Instrucciones de compilación (Linux)](development/build-instructions-linux.md) +* [Configurando un servidor de símbolos en el depurador](development/setting-up-symbol-server.md) diff --git a/docs/tutorial/application-distribution-es.md b/docs/tutorial/application-distribution-es.md new file mode 100644 index 000000000000..644da8c3c87b --- /dev/null +++ b/docs/tutorial/application-distribution-es.md @@ -0,0 +1,114 @@ +# Distribución de aplicaciones + +Para distribuir tu aplicación con Electron, debes nombrar al directorio de tu aplicación +como `app`, y ponerlo bajo el directorio de recursos de Electron (en OSX es `Electron.app/Contents/Resources/`, +en Linux y Windows es `resources/`): + +En OSX: + +```text +electron/Electron.app/Contents/Resources/app/ +├── package.json +├── main.js +└── index.html +``` + +En Windows y Linux: + +```text +electron/resources/app +├── package.json +├── main.js +└── index.html +``` + +Posteriormente ejecutas `Electron.app` (o `electron` en Linux, `electron.exe` en Windows), +y Electron iniciará la aplicación. El directorio `electron` será la distribución que recibirán los usuarios finales. + +## Empaquetando tu aplicación como un archivo + +Además de copiar todos tus archivos fuente para la distribución, también puedes +empaquetar tu aplicación como un archivo [asar](https://github.com/atom/asar) +y de esta forma evitar la exposición del código fuente de tu aplicación a los usuarios. + +Para usar un archivo `asar` en reemplazo de la carpeta `app`, debes renombrar +el archivo a `app.asar`, y ponerlo bajo el directorio de recursos de Electron (como arriba), +Electron intentará leer el archivo y ejecutar la aplicación desde él. + +En OS X: + +```text +electron/Electron.app/Contents/Resources/ +└── app.asar +``` + +En Windows y Linux: + +```text +electron/resources/ +└── app.asar +``` + +Más detalles en [Empaquetamiento de aplicaciones](application-packaging-es.md). + +## Rebranding con binarios descargados + +Luego de empaquetar tu aplicación con Electron, podría ser útil agregar tu marca +antes de realizar la distribución. + +### Windows + +Puedes renombrar `electron.exe` a cualquier nombre que desees, y editar su ícono y otras informaciones +con herramientas como [rcedit](https://github.com/atom/rcedit) o [ResEdit](http://www.resedit.net). + +### OS X + +Puedes renombrar `Electron.app` a cualquier nombre que desees. También debes modificar los campos +`CFBundleDisplayName`, `CFBundleIdentifier` y `CFBundleName` en los siguientes archivos: + +* `Electron.app/Contents/Info.plist` +* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` + +También puedes renombrar el helper de la aplicación para evitar que aparezca como `Electron Helper` +en el Monitor de Actividades. + +La estructura de una aplicación renombrada sería así: + +``` +MyApp.app/Contents +├── Info.plist +├── MacOS/ +│   └── MyApp +└── Frameworks/ + ├── MyApp Helper EH.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper EH + ├── MyApp Helper NP.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper NP + └── MyApp Helper.app + ├── Info.plist + └── MacOS/ +    └── MyApp Helper +``` + +### Linux + +Puedes renombrar el ejectuable `electron` a cualquier nombre que desees. + +## Rebranding desde el código fuente de Electron + +También es posible agregar tu marca a Electron mediante un build personalizado. +Para realizar esto debes modificar el archivo `atom.gyp`. + +### grunt-build-atom-shell + +La modificación del código de Electron para agregar tu marca puede resultar complicada, una tarea Grunt +se ha creado para manejar esto de forma automatizada: + +[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). + +Esta tarea se encargará de modificar el archivo `.gyp`, compilar el código +y reconstruir los módulos nativos de la aplicación para que coincidan con el nuevo nombre. diff --git a/docs/tutorial/application-packaging-es.md b/docs/tutorial/application-packaging-es.md new file mode 100644 index 000000000000..56698c1aaecb --- /dev/null +++ b/docs/tutorial/application-packaging-es.md @@ -0,0 +1,157 @@ +# Empaquetamiento de aplicaciones + +Para proteger los recursos y el código fuente de tu aplicación, puedes optar por empaquetar +tu aplicación en un paquete [asar][asar]. + +## Generando un archivo `asar` + +Un paquete [asar][asar] es un formato sencillo similar a tar, este formato concatena todos los archivos en uno, +Electron puede leer el contenido sin desempaquetar todos los archivos. + +A continuación, los pasos para empaquetar tu aplicación con `asar`: + +### 1. Instalar asar + +```bash +$ npm install -g asar +``` + +### 2. Empaquetar utilizando `asar pack` + +```bash +$ asar pack your-app app.asar +``` + +## Utilizando los paquetes `asar` + +En Electron existen dos tipos de APIs: las APIs de Node, proveídas por Node.js, +y las APIs Web, proveídas por Chromium. Ambas APIs soportan la lecutra de paquetes `asar`. + +### API Node + +Con parches especiales en Electron, las APIs de Node como `fs.readFile` and `require` +tratan los paquetes `asar` como directorios virtuales, y el contenido es accesible como si se tratara +de archivos normales en el sistema de archivos. + +Por ejemplo, supongamos que tenemos un paquete `example.asar` bajo `/path/to`: + +```bash +$ asar list /path/to/example.asar +/app.js +/file.txt +/dir/module.js +/static/index.html +/static/main.css +/static/jquery.min.js +``` + +Leer un archivo de nuestro paquete `asar`: + +```javascript +var fs = require('fs'); +fs.readFileSync('/path/to/example.asar/file.txt'); +``` + +Listar todos los archivos de la raíz: + +```javascript +var fs = require('fs'); +fs.readdirSync('/path/to/example.asar'); +``` + +Utilizar un módulo que se encuentra dentro del archivo: + +```javascript +require('/path/to/example.asar/dir/module.js'); +``` + +También puedes mostrar una página web contenida en un `asar` utilizando `BrowserWindow`. + +```javascript +var BrowserWindow = require('browser-window'); +var win = new BrowserWindow({width: 800, height: 600}); +win.loadUrl('file:///path/to/example.asar/static/index.html'); +``` + +### API Web + +En una págin web, los archivos que se encuentran en el paquete son accesibles a través del protocolo `file:`. +Al igual que la API Node, los paquetes `asar` son tratados como directorios. + +Por ejemplo, para obtener un archivo con `$.get`: + +```html + +``` + +### Utilizando un paquete `asar` como un archivo normal + +En algunas situaciones necesitaremos acceder al paquete `asar` como archivo, por ejemplo, +si necesitaramos verificar la integridad del archivo con un checksum. +Para casos así es posible utilizar el módulo `original-fs`, que provee la API `fs` original: + +```javascript +var originalFs = require('original-fs'); +originalFs.readFileSync('/path/to/example.asar'); +``` + +## Limitaciones de la API Node: + +A pesar de que hemos intentado que los paquetes `asar` funcionen como directorios de la mejor forma posible, +aún existen limitaciones debido a la naturaleza de bajo nivel de la API Node. + +### Los paquetes son de sólo lecutra + +Los paquetes `asar` no pueden ser modificados, por lo cual todas las funciones que modifiquen archivos +no funcionarán. + +## Los directorios del paquete no pueden establecerse como working directories + +A pesar de que los paquetes `asar` son manejados virtualmente como directorios, +estos directorios no existen en el sistema de archivos, por lo cual no es posible establecerlos +como working directory, el uso de la opción `cwd` en algunas APIs podría causar errores. + +### Desempaquetamiento adicional en algunas APIs + +La mayoría de las APIs `fs` pueden leer u obtener información sobre un archivo en un paquete `asar` sin +la necesidad de desempaquetarlo, pero algunas APIs requieren la ruta real. En estos casos Electron extraerá +el archivo a una ruta temporal. Esto agrega un overhead a algunas APIs. + +Las APIs que requieren el desempaquetamiento adicional son: + +* `child_process.execFile` +* `fs.open` +* `fs.openSync` +* `process.dlopen` - Utilizado po `require` en los módulos nativos + +### Información falsa en `fs.stat` + +El objeto `Stats` retornado por `fs.stat` y otras funciones relacionadas, +no es preciso, ya que los archivos del paquete `asar` no existen el sistema de archivos. +La utilización del objeto `Stats` sólo es recomendable para obtener el tamaño del archivo y/o +comprobar el tipo de archivo. + + +## Agregando archivos al paquete `asar` + +Como se menciona arriba, algunas APIs de Node desempaquetarán archivos cuando exista una llamada +que los referencie, además de los problemas de rendimiento que esto podría ocasionar, también +podría accionar alertas falsas en software antivirus. + +Para lidiar con esto, puedes desempaquetar algunos archivos utilizando la opción `--unpack`, +a continuación un ejemplo que excluye las librerías compartidas de los módulos nativos: + +```bash +$ asar pack app app.asar --unpack *.node +``` + +Después de ejecutar este comando, además del archivo `app.asar`, también se creará +un directorio `app.asar.unpacked`, que contendrá los archivos desempaquetados. +Este directorio deberá copiarse junto con el archivo `app.asar` a la hora de distribuir la aplicación. + +[asar]: https://github.com/atom/asar diff --git a/docs/tutorial/debugging-main-process-es.md b/docs/tutorial/debugging-main-process-es.md new file mode 100644 index 000000000000..1a764036e37a --- /dev/null +++ b/docs/tutorial/debugging-main-process-es.md @@ -0,0 +1,45 @@ +# Depurando el proceso principal + +Los devtools sólo pueden depurar las páginas web (el código del proceso renderer). +Para depurar el código del proceso principal, Electron provee dos opciones para la línea de comandos: `--debug` y `--debug-brk`. + +## Opciones para la línea de comandos + +### `--debug=[port]` + +Esta opción escuchará mensajes del protocolo de depuración V8 en `port`, por defecto `port` es `5858`. + +### `--debug-brk=[port]` + +Similar a `--debug` pero realiza una pausa en la primera línea del script. + +## Utilizando node-inspector para depuración + +__Nota:__ Electron utiliza node v0.11.13, esta versión aún no funciona bien con node-inspector, +el proceso principal podría fallar al inspeccionar el objeto `process`. + +### 1. Iniciar [node-inspector][node-inspector] + +```bash +$ node-inspector +``` + +### 2. Activar el modo de depuración en Electron + +Es posible iniciar Electron con la opción de depuración: + +```bash +$ electron --debug=5858 your/app +``` + +o, pausar el script en la primera línea: + +```bash +$ electron --debug-brk=5858 your/app +``` + +### 3. Cargar la interfaz del depurador + +Abre http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 en Chrome. + +[node-inspector]: https://github.com/node-inspector/node-inspector diff --git a/docs/tutorial/desktop-environment-integration-es.md b/docs/tutorial/desktop-environment-integration-es.md new file mode 100644 index 000000000000..f19f36326f3e --- /dev/null +++ b/docs/tutorial/desktop-environment-integration-es.md @@ -0,0 +1,171 @@ +# Integración con el entorno de escritorio + +Los sistemas operativos proveen diferentes características para integrar aplicaciones +en sus entornos de escritorio. Por ejemplo, en Windows, las aplicaciones pueden agregar accesos directos +en la JumpList de la barra de tareas, y en Mac, las aplicaciones pueden agregar un menú personalizado en el dock. + +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) + +Windows y OS X proveen un acceso sencillo a la lista de documentos recientes. + +__JumpList:__ + +![JumpList, Archivos recientes](http://i.msdn.microsoft.com/dynimg/IC420538.png) + +__Menú Dock:__ + + + +Para agregar un archivo a la lista de documentos recientes, puedes utilizar: +[app.addRecentDocument][addrecentdocument] API: + +```javascript +var app = require('app'); +app.addRecentDocument('/Users/USERNAME/Desktop/work.type'); +``` + +También puedes utilizar [app.clearRecentDocuments](clearrecentdocuments) para vaciar la lista de documentos recientes: + +```javascript +app.clearRecentDocuments(); +``` + +### Notas sobre Windows + +Para activar esta característica en Windows, tu aplicación debe registrar un handler +para el tipo de archivo que quieres utilizar, de lo contrario el archivo no aparecerá +en la JumpList, aún después de agregarlo. Puedes encontrar más información sobre el proceso de +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 + +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) + +OS X 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: + +__Menú dock de Terminal.app:__ + + + +Para establecer tu menú dock, puedes utilizar la API `app.dock.setMenu`, la cual sólo está disponible para OSX: + +```javascript +var app = require('app'); +var Menu = require('menu'); +var dockMenu = Menu.buildFromTemplate([ + { label: 'New Window', click: function() { console.log('New Window'); } }, + { label: 'New Window with Settings', submenu: [ + { label: 'Basic' }, + { label: 'Pro'} + ]}, + { label: 'New Command...'} +]); +app.dock.setMenu(dockMenu); +``` + +## Tareas de usuario (Windows) + +En Windows puedes especificar acciones personalizadas en la categoría `Tasks` del JumpList, +tal como menciona MSDN: + + +> Las aplicaciones definen tareas basadas en las características del programa +> y las acciones clave que se esperan de un usuario. Las tareas deben ser +> libres de contexto, es decir, la aplicación no debe encontrarse en ejecución +> para que estas acciones funcionen. También deberían ser las acciones estadísticamente +> más comunes que un usuario normal realizaría en tu aplicación, como por ejemplo, +> redactar un mensaje de correo electrónico, crear un documento en el procesador de textos, +> ejecutar una aplicación en cierto modo, o ejecutar alguno de sus subcomandos. Una aplicación +> no debería popular el menú con características avanzadas que el usuario estándar no necesita +> ni con acciones que sólo se realizan una vez, como por ejemplo, el registro. No utilices +> las tareas para mostrar elementos promocionales como actualizaciones u ofertas especiales. +> +> Es recomendable que la lista de tareas sea estática. Debe mantenerse a pesar +> de los cambios de estado de la aplicación. Aunque exista la posibilidad de variar +> el contenido de la lista dinámicamente, debes considerar que podría ser confuso +> para un usuario que no espera que el destino de la lista cambie. + +__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 +funcionan como accesos directos de aplicación, que al ser clickeados, lanzan el programa +con argumentos específicos. + +Para establecer las tareas de usuario en tu aplicación, puedes utilizar: +[app.setUserTasks][setusertaskstasks] API: + +```javascript +var app = require('app'); +app.setUserTasks([ + { + program: process.execPath, + arguments: '--new-window', + iconPath: process.execPath, + iconIndex: 0, + title: 'New Window', + description: 'Create a new window' + } +]); +``` + +Para purgar la lista de tareas, puedes llamar a `app.setUserTasks` con un array vacío: + +```javascript +app.setUserTasks([]); +``` + +Las tareas de usuario aún serán visibles después de cerrar tu aplicación, por lo cual +el ícono y la ruta del programa deben existir hasta que la aplicación sea desinstalada. + +## Accesos directos en el lanzador Unity (Linux) + +En Unity, es posible agregar algunas entradas personalizadas, modificando el archivo `.desktop`, +ver [Adding shortcuts to a launcher][unity-launcher]. + +__Accesos directos de Audacious:__ + +![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png) + +## Barra de progreso en la barra de tareas (Windows y Unity) + +En Windows, un botón en la barra de tareas puede utilizarse para mostrar una barra de progreso. Esto permite +que una ventana muestre la información de progreso al usuario, sin que el usuario tenga la ventana de la aplicación activa. + +El entorno de escritorio Unity también posee una característica similar que permite mostrar una barra de progreso en el lanzador. + +__Barra de progreso en un botón de la barra de herramientas:__ + +![Taskbar Progress Bar](https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png) + +__Barra de progreso en el lanzador Unity:__ + +![Unity Launcher](https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png) + +Para establecer la barra de progreso de una ventana, puedes utilizar +[BrowserWindow.setProgressBar][setprogressbar] API: + +```javascript +var window = new BrowserWindow({...}); +window.setProgressBar(0.5); +``` + +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks +[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename +[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx +[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher diff --git a/docs/tutorial/devtools-extension-es.md b/docs/tutorial/devtools-extension-es.md new file mode 100644 index 000000000000..f54c3e0eaa83 --- /dev/null +++ b/docs/tutorial/devtools-extension-es.md @@ -0,0 +1,49 @@ +# Extensión DevTools + +Para facilitar la depuración, Electron provee un soporte básico para la extensión +[Chrome DevTools Extension][devtools-extension]. + +Para la mayoría de las extensiones devtools, simplemente puedes descargar el código fuente +y utilizar `BrowserWindow.addDevToolsExtension` para cargarlas, las extensiones cargadas +serán recordadas para que no sea necesario llamar a la función cada vez que creas una ventana. + +Por ejemplo, para usar la extensión [React DevTools Extension](https://github.com/facebook/react-devtools), primero debes descargar el código fuente: + +```bash +$ cd /some-directory +$ git clone --recursive https://github.com/facebook/react-devtools.git +``` + +Luego cargas la aplicación en Electron, abriendo devtools en cualquier ventana, +y ejecutando este código en la consola devtools: + +```javascript +require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools'); +``` + +Para remover una extensión, puedes utilizar `BrowserWindow.removeDevToolsExtension` +especificando el nombre, y esta ya no se cargará la siguiente vez que abras devtools: + +```javascript +require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools'); +``` + +## Formato de las extensiones devtools + +Idealmente todas las extensiones devtools escritas para Chrome pueden ser cargadas por Electron, +pero para ello deben estar en un directorio plano, las extensiones empaquetadas como `crx` +no pueden ser cargadas por Chrome a no ser que halles una forma de extraerlas a un directorio. + +## Páginas en segundo plano (background) + +Electron no soporta la característica de páginas en segundo plano de las extensiones de Chrome, +las extensiones que utilizan esta característica podrían no funcionar. + +## APIs `chrome.*` + +Algunas extensiones utilizan las APIs `chrome.*`, hemos realizado un esfuerzo +para implementar esas APIs en Electron, sin embargo no han sido implementadas en su totalidad. + +Dado que no todas las funciones `chrome.*` han sido implementadas, si la extensión devtools está utilizando otras APIs más allá de `chrome.devtools.*`, es muy probable que no funcione. Puedes reportar fallos en el issue tracker para que podamos agregar soporte a esas APIs. + +[devtools-extension]: https://developer.chrome.com/extensions/devtools diff --git a/docs/tutorial/online-offline-events-es.md b/docs/tutorial/online-offline-events-es.md new file mode 100644 index 000000000000..0e43f9b16109 --- /dev/null +++ b/docs/tutorial/online-offline-events-es.md @@ -0,0 +1,80 @@ +# Detección del evento en línea/fuera de línea + +La detección de estos eventos puede ser implementada en el proceso renderer utilizando las APIs HTML5 estándar, +como en este ejemplo: + +_main.js_ + +```javascript +var app = require('app'); +var BrowserWindow = require('browser-window'); +var onlineStatusWindow; + +app.on('ready', function() { + onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); + onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); +}); +``` + +_online-status.html_ + +```html + + + + + + +``` + +Existen casos en donde necesitas responder a estos eventos desde el proceso principal. +El proceso principal no posee un objeto `navigator`, por lo tanto no puede detectar estos eventos directamente. +Es posible reenviar el evento al proceso principal mediante la utilidad de intercomunicación entre procesos (ipc): + +_main.js_ + +```javascript +var app = require('app'); +var ipc = require('ipc'); +var BrowserWindow = require('browser-window'); +var onlineStatusWindow; + +app.on('ready', function() { + onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); + onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); +}); + +ipc.on('online-status-changed', function(event, status) { + console.log(status); +}); +``` + +_online-status.html_ + +```html + + + + + + +``` diff --git a/docs/tutorial/quick-start-es.md b/docs/tutorial/quick-start-es.md new file mode 100644 index 000000000000..5c3095deb3ef --- /dev/null +++ b/docs/tutorial/quick-start-es.md @@ -0,0 +1,154 @@ +# Intro + +## Introducción + +Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado en aplicaciones de escritorio, en vez de servidores web. + +Esto no significa que Electron sea un binding de librerías GUI para JavaScript. +Electron utiliza páginas web como su GUI, por lo cual puedes verlo como un navegador Chromium mínimo, +controlado por JavaScript. + +### El proceso principal (main process) + +En Electron, el proceso que ejecuta el script `main` del `package.json` se llama __el proceso principal__. +El script que corre en el proceso principal puede crear páginas para mostrar la GUI. + +### El proceso renderer (renderer process) + +Dado que Electron utiliza Chromium para mostrar las páginas web, +también es utilizada la arquitectura multiproceso de Chromium. +Cada página web en Electron se ejecuta en su propio proceso, +el cual es llamado __el proceso renderer__. + +En los navegadores normales, las páginas web usualmente se ejecutan en un entorno +sandbox y no tienen acceso a los recursos nativos. Los usuarios de Electron tienen el poder +de utilizar las APIs de io.js en las páginas web, permitiendo interacciones de bajo nivel con el sistema operativo. + +### Diferencias entre el proceso principal y el proceso renderer + +El proceso principal crea páginas web mediante instancias de `BrowserWindow`. Cada instancia de `BrowserWindow` ejecuta su propia página web y su propio proceso renderer. +Cuando una instancia de `BrowserWindow` es destruida, también su proceso renderer correspondiente acaba. + +El proceso principal gestiona las páginas web y sus correspondientes procesos renderer. +Cada proceso renderer es aislado y sólo considera relevante la página web que corre en él. + +En las páginas web, no está permitido llamar a APIs relacionadas a la GUI nativa +porque la gestión de los recursos GUI nativos es peligrosa, y tiende a que ocurran leaks de memoria. +Si deseas realizar operaciones GUI en una página web, el proceso renderer de la página web debe comunicarse +con el proceso principal, y solicitar a este que realice esas operaciones. + +En Electron, hemos proveído el módulo [ipc](../api/ipc-renderer.md) para la comunicación +entre el proceso principal y el proceso renderer. Y también hay un módulo [remote](../api/remote.md) +para comunicación al estilo RPC. + +## Escribe tu primera aplicación Electron + +Generalmente, una aplicación Electron tendrá la siguiente estructura: + +```text +your-app/ +├── package.json +├── main.js +└── index.html +``` + +El formato de `package.json` es exactamente el mismo que cualquier módulo Node, +y el script especificado en el campo `main` será el script de arranque de tu aplicación, +a ser ejecutado por el proceso principal. Un ejemplo de `package.json` podría verse así: + +```json +{ + "name" : "your-app", + "version" : "0.1.0", + "main" : "main.js" +} +``` + +El `main.js` debería crear las ventanas y gestionar los eventos del sistema, un ejemplo típico sería: +example being: + +```javascript +var app = require('app'); // Módulo para controlar el ciclo de vida de la aplicación. +var BrowserWindow = require('browser-window'); // Módulo para crear uan ventana de navegador. + +// Reportar crashes a nuestro servidor. +require('crash-reporter').start(); + +// Mantener una referencia global al objeto window, si no lo haces, esta ventana +// se cerrará automáticamente cuando el objeto JavaScript sea recolectado (garbage collected): +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ú + // se mantengan activas hasta que el usuario cierre la aplicación + // explícitamente utilizando Cmd + Q + if (process.platform != 'darwin') { + app.quit(); + } +}); + +// Este método será llamado cuando Electron haya finalizado la inicialización +// y esté listo para crear ventanas de navegador. +app.on('ready', function() { + // Crear la ventana. + mainWindow = new BrowserWindow({width: 800, height: 600}); + + // cargar el index.html de nuestra aplicación. + mainWindow.loadUrl('file://' + __dirname + '/index.html'); + + // Desplegar devtools. + mainWindow.openDevTools(); + + // Evento emitido cuando se cierra la ventana. + mainWindow.on('closed', function() { + // Eliminar la referencia del objeto window. + // En el caso de soportar multiples ventanas, es usual almacenar + // los objetos window en un array, este es el momento en el que debes eliminar el elemento correspondiente. + mainWindow = null; + }); +}); +``` + +Finalmente el `index.html` es la página web que mostraremos: + +```html + + + + Hello World! + + +

Hello World!

+ We are using io.js + and Electron . + + +``` + +## Ejecutar la aplicación + +Cuando termines de escribir tu aplicación, puedes distribuirla +siguiendo la [guía de distribución](./application-distribution-es.md) +y luego ejecutar la aplicación empaquetada. También puedes utilizar el binario de Electron +para ejecutar tu aplicación de forma directa. + +En Windows: + +```bash +$ .\electron\electron.exe your-app\ +``` + +En Linux: + +```bash +$ ./electron/electron your-app/ +``` + +En OS X: + +```bash +$ ./Electron.app/Contents/MacOS/Electron your-app/ +``` + +`Electron.app` es parte del paquete de release de Electron, puedes descargarlo [aquí](https://github.com/atom/electron/releases). diff --git a/docs/tutorial/using-native-node-modules-es.md b/docs/tutorial/using-native-node-modules-es.md new file mode 100644 index 000000000000..78409049ad93 --- /dev/null +++ b/docs/tutorial/using-native-node-modules-es.md @@ -0,0 +1,57 @@ +# Utilizando módulos Node nativos + +Los módulos Node nativos son soportados por Electron, pero dado que Electron +está utilizando una versión distinta de V8, debes especificar manualmente la +ubicación de las cabeceras de Electron a la hora de compilar módulos nativos. + +## Compatibilidad de módulos nativos + +A partir de Node v0.11.x han habido cambios vitales en la API de V8. +Es de esperar que los módulos escritos para Node v0.10.x no funcionen con Node v0.11.x. +Electron utiliza Node v.0.11.13 internamente, y por este motivo tiene el mismo problema. + +Para resolver esto, debes usar módulos que soporten Node v0.11.x, +[muchos módulos](https://www.npmjs.org/browse/depended/nan) soportan ambas versiones. +En el caso de los módulos antiguos que sólo soportan Node v0.10.x, debes usar el módulo +[nan](https://github.com/rvagg/nan) para portarlos a v0.11.x. + +## ¿Cómo instalar módulos nativos? + +### La forma fácil + +La forma más sencilla de recompilar módulos nativos es a través del paquete +[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild), +el cual abstrae y maneja los pasos de descargar las cabeceras y compilar los módulos nativos: + +```sh +npm install --save-dev electron-rebuild + +# Ejecuta esto cada vez que ejecutes npm install +./node_modules/.bin/electron-rebuild +``` + +### La forma node-gyp + +Para compilar módulos Node con las cabeceras de Electron, debes indicar a `node-gyp` +desde dónde descargar las cabeceras y cuál versión usar: + +```bash +$ cd /path-to-module/ +$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell +``` + +Los cambios en `HOME=~/.electron-gyp` fueron para especificar la ruta de las cabeceras. +La opción `--target=0.29.1` es la versión de Electron. La opción `--dist-url=...` especifica +dónde descargar las cabeceras. `--arch=x64` indica que el módulo será compilado para un sistema de 64bit. + +### La forma npm + +También puedes usar `npm` para instalar módulos, los pasos son exactamente igual a otros módulos Node, +con la excepción de que necesitas establecer algunas variables de entorno primero: + +```bash +export npm_config_disturl=https://atom.io/download/atom-shell +export npm_config_target=0.29.1 +export npm_config_arch=x64 +HOME=~/.electron-gyp npm install module-name +``` diff --git a/docs/tutorial/using-pepper-flash-plugin-es.md b/docs/tutorial/using-pepper-flash-plugin-es.md new file mode 100644 index 000000000000..fbb2b6f83aa0 --- /dev/null +++ b/docs/tutorial/using-pepper-flash-plugin-es.md @@ -0,0 +1,58 @@ +# Utilizando el plugin Pepper Flash + +El plugin Pepper Flash es soportado ahora. Para utilizar pepper flash en Electron, debes especificar la ubicación del plugin manualmente y activarlo en tu aplicación. + +## Preparar una copia del plugin Flash + +En OSX y Linux, el detalle del plugin puede encontrarse accediendo a `chrome://plugins` en el navegador. Su ubicación y versión son útiles para el soporte. También puedes copiarlo a otro lugar. + +## Agrega la opción a Electron + +Puedes agregar la opción `--ppapi-flash-path` y `ppapi-flash-version` o utilizar el método `app.commandLine.appendSwitch` antes del evento ready de la aplicación. +También puedes agregar la opción `plugins` de `browser-window`. Por ejemplo, + +```javascript +var app = require('app'); +var BrowserWindow = require('browser-window'); + +// Report crashes to our server. +require('crash-reporter').start(); + +// Keep a global reference of the window object, if you don't, the window will +// be closed automatically when the javascript object is GCed. +var mainWindow = null; + +// Quit when all windows are closed. +app.on('window-all-closed', function() { + if (process.platform != 'darwin') { + app.quit(); + } +}); + +// Specify flash path. +// On Windows, it might be /path/to/pepflashplayer.dll +// On Mac, /path/to/PepperFlashPlayer.plugin +// On Linux, /path/to/libpepflashplayer.so +app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); + +// Specify flash version, for example, v17.0.0.169 +app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169'); + +app.on('ready', function() { + mainWindow = new BrowserWindow({ + 'width': 800, + 'height': 600, + 'web-preferences': { + 'plugins': true + } + }); + mainWindow.loadUrl('file://' + __dirname + '/index.html'); + // Something else +}); +``` + +## Activar el plugin flash en una etiqueta `` +Agrega el atributo `plugins`. +```html + +``` diff --git a/docs/tutorial/using-selenium-and-webdriver-es.md b/docs/tutorial/using-selenium-and-webdriver-es.md new file mode 100644 index 000000000000..7d9989057056 --- /dev/null +++ b/docs/tutorial/using-selenium-and-webdriver-es.md @@ -0,0 +1,72 @@ +# Utilizando Selenium y WebDriver + +De [ChromeDriver - WebDriver for Chrome][chrome-driver]: + +> WebDriver es una herramienta de código abierto para automatizar el testing de aplicaciones web +> en varios navegadores. WebDriver provee funciones de navegación, entrada de usuario, +> ejecución de JavaScript, y más. ChromeDriver es un servidor standalone que implementa +> el protocolo de WebDriver para Chromium. Se encuentra en desarrollo por los miembros de +> Chromium y WebDriver. + +En la página de [lanzamientos](https://github.com/atom/electron/releases) de Electron encontrarás paquetes de `chromedriver`. + +## Ajustando parámetros con WebDriverJs + +[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provee +un paquete Node para realizar testing con web driver, lo usaremos como ejemplo. + +### 1. Inicia chrome driver + +Primero necesitas descargar el binario `chromedriver` y ejecutarlo: + +```bash +$ ./chromedriver +Starting ChromeDriver (v2.10.291558) on port 9515 +Only local connections are allowed. +``` + +Recuerda el puerto `9515`, lo utilizaremos después. + +### 2. Instala WebDriverJS + +```bash +$ npm install selenium-webdriver +``` + +### 3. Conecta chrome driver + +El uso de `selenium-webdriver` junto con Electron es básicamente el mismo que el original, +excepto que necesitas especificar manualmente cómo se conectará el chrome driver +y dónde encontrará el binario de Electron: + +```javascript +var webdriver = require('selenium-webdriver'); + +var driver = new webdriver.Builder() + // El puerto "9515" es que abre chrome driver. + .usingServer('http://localhost:9515') + .withCapabilities({chromeOptions: { + // Aquí especificamos la ruta a Electron + binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}) + .forBrowser('electron') + .build(); + +driver.get('http://www.google.com'); +driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); +driver.findElement(webdriver.By.name('btnG')).click(); +driver.wait(function() { + return driver.getTitle().then(function(title) { + return title === 'webdriver - Google Search'; + }); +}, 1000); + +driver.quit(); +``` + +## Workflow + +Para probar tu aplicación sin recompilar Electron, simplemente [copia](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) las fuentes de tu aplicación en el directorio de recursos de Electron. + +[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ + + From ad7e4a77db83a1790a2d3e92e3b1541560f99355 Mon Sep 17 00:00:00 2001 From: Matias Insaurralde Date: Sun, 26 Jul 2015 22:59:19 -0400 Subject: [PATCH 054/172] custom dom texts --- docs/README-es.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/README-es.md b/docs/README-es.md index 991c80b069f3..a278de95bd43 100644 --- a/docs/README-es.md +++ b/docs/README-es.md @@ -22,9 +22,9 @@ Elementos DOM customizados: -* [`File` object](api/file-object.md) -* [`` tag](api/web-view-tag.md) -* [`window.open` function](api/window-open.md) +* [Objeto `File`](api/file-object.md) +* [Etiqueta ``](api/web-view-tag.md) +* [Función `window.open`](api/window-open.md) Módulos del proceso principal: From 9211109088cce2855a27f7a921abe5eb45d567c2 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Sun, 26 Jul 2015 21:58:48 -0700 Subject: [PATCH 055/172] Add NativeImage.IsTemplateImage method * Rename internal function that determines template image filename patterns * Add the new IsTemplateMethod --- atom/common/api/atom_api_native_image.cc | 7 +++++-- atom/common/api/atom_api_native_image.h | 2 ++ atom/common/api/atom_api_native_image_mac.mm | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index bd66ad511f75..af173dda3e9a 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -113,7 +113,7 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image, } #if defined(OS_MACOSX) -bool IsTemplateImage(const base::FilePath& path) { +bool IsTemplateFilename(const base::FilePath& path) { return (MatchPattern(path.value(), "*Template.*") || MatchPattern(path.value(), "*Template@*x.*")); } @@ -139,6 +139,7 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( .SetMethod("isEmpty", &NativeImage::IsEmpty) .SetMethod("getSize", &NativeImage::GetSize) .SetMethod("setTemplateImage", &NativeImage::SetTemplateImage) + .SetMethod("isTemplateImage", &NativeImage::IsTemplateImage) .Build()); return mate::ObjectTemplateBuilder( @@ -180,6 +181,8 @@ gfx::Size NativeImage::GetSize() { #if !defined(OS_MACOSX) void NativeImage::SetTemplateImage(bool setAsTemplate) { } +bool NativeImage::IsTemplateImage() { +} #endif // static @@ -217,7 +220,7 @@ mate::Handle NativeImage::CreateFromPath( gfx::Image image(image_skia); mate::Handle handle = Create(isolate, image); #if defined(OS_MACOSX) - if (IsTemplateImage(path)) + if (IsTemplateFilename(path)) handle->SetTemplateImage(true); #endif return handle; diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 8cb43d06e152..1f0fe946ba51 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -67,6 +67,8 @@ class NativeImage : public mate::Wrappable { // Mark the image as template image. void SetTemplateImage(bool setAsTemplate); + // Determine if the image is a template image. + bool IsTemplateImage(); gfx::Image image_; diff --git a/atom/common/api/atom_api_native_image_mac.mm b/atom/common/api/atom_api_native_image_mac.mm index a80462766bc2..a9e5225b815d 100644 --- a/atom/common/api/atom_api_native_image_mac.mm +++ b/atom/common/api/atom_api_native_image_mac.mm @@ -14,6 +14,10 @@ void NativeImage::SetTemplateImage(bool setAsTemplate) { [image_.AsNSImage() setTemplate:setAsTemplate]; } +bool NativeImage::IsTemplateImage() { + return [image_.AsNSImage() isTemplate]; +} + } // namespace api } // namespace atom From 51111430b3ca75a2616108ae876f0457d626c613 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Sun, 26 Jul 2015 21:59:43 -0700 Subject: [PATCH 056/172] Add NativeImage docs for IsTemplateImage --- docs/api/native-image.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index ed12819d26c4..5c6bf11659c5 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -132,6 +132,10 @@ Returns the size of the image. [buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer +### NativeImage.isTemplateImage() + +Returns whether the image is a template image. + ### NativeImage.setTemplateImage(option) * `option` Boolean From 99a8f29de9db1c415a0352d669e6177afb1c4421 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Mon, 27 Jul 2015 00:41:20 -0700 Subject: [PATCH 057/172] Move event type functions to a common event_util file --- atom/browser/ui/cocoa/atom_menu_controller.mm | 50 +------------------ atom/browser/ui/event_util.h | 17 +++++++ atom/browser/ui/event_util_mac.mm | 47 +++++++++++++++++ filenames.gypi | 2 + 4 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 atom/browser/ui/event_util.h create mode 100644 atom/browser/ui/event_util_mac.mm diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 176f2db7e145..fbfaea94110f 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -4,6 +4,7 @@ // found in the LICENSE file. #import "atom/browser/ui/cocoa/atom_menu_controller.h" +#import "atom/browser/ui/event_util.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" @@ -13,53 +14,6 @@ #include "ui/base/models/simple_menu_model.h" #include "ui/gfx/image/image.h" -namespace { - -bool isLeftButtonEvent(NSEvent* event) { - NSEventType type = [event type]; - return type == NSLeftMouseDown || - type == NSLeftMouseDragged || - type == NSLeftMouseUp; -} - -bool isRightButtonEvent(NSEvent* event) { - NSEventType type = [event type]; - return type == NSRightMouseDown || - type == NSRightMouseDragged || - type == NSRightMouseUp; -} - -bool isMiddleButtonEvent(NSEvent* event) { - if ([event buttonNumber] != 2) - return false; - - NSEventType type = [event type]; - return type == NSOtherMouseDown || - type == NSOtherMouseDragged || - type == NSOtherMouseUp; -} - -int EventFlagsFromNSEventWithModifiers(NSEvent* event, NSUInteger modifiers) { - int flags = 0; - flags |= (modifiers & NSAlphaShiftKeyMask) ? ui::EF_CAPS_LOCK_DOWN : 0; - flags |= (modifiers & NSShiftKeyMask) ? ui::EF_SHIFT_DOWN : 0; - flags |= (modifiers & NSControlKeyMask) ? ui::EF_CONTROL_DOWN : 0; - flags |= (modifiers & NSAlternateKeyMask) ? ui::EF_ALT_DOWN : 0; - flags |= (modifiers & NSCommandKeyMask) ? ui::EF_COMMAND_DOWN : 0; - flags |= isLeftButtonEvent(event) ? ui::EF_LEFT_MOUSE_BUTTON : 0; - flags |= isRightButtonEvent(event) ? ui::EF_RIGHT_MOUSE_BUTTON : 0; - flags |= isMiddleButtonEvent(event) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0; - return flags; -} - -// Retrieves a bitsum of ui::EventFlags from NSEvent. -int EventFlagsFromNSEvent(NSEvent* event) { - NSUInteger modifiers = [event modifierFlags]; - return EventFlagsFromNSEventWithModifiers(event, modifiers); -} - -} // namespace - @interface AtomMenuController (Private) - (void)addSeparatorToMenu:(NSMenu*)menu atIndex:(int)index; @@ -246,7 +200,7 @@ int EventFlagsFromNSEvent(NSEvent* event) { [[sender representedObject] pointerValue]); DCHECK(model); if (model) { - int event_flags = EventFlagsFromNSEvent([NSApp currentEvent]); + int event_flags = event_util::EventFlagsFromNSEvent([NSApp currentEvent]); model->ActivatedAt(modelIndex, event_flags); } } diff --git a/atom/browser/ui/event_util.h b/atom/browser/ui/event_util.h new file mode 100644 index 000000000000..59a624d6bf96 --- /dev/null +++ b/atom/browser/ui/event_util.h @@ -0,0 +1,17 @@ +#ifndef ATOM_BROWSER_UI_EVENT_UTIL_H_ +#define ATOM_BROWSER_UI_EVENT_UTIL_H_ + +#import + +namespace event_util { + +bool isLeftButtonEvent(NSEvent* event); +bool isRightButtonEvent(NSEvent* event); +bool isMiddleButtonEvent(NSEvent* event); + +// Retrieves a bitsum of ui::EventFlags from NSEvent. +int EventFlagsFromNSEvent(NSEvent* event); + +} // namespace event_util + +#endif // ATOM_BROWSER_UI_EVENT_UTIL_H_ diff --git a/atom/browser/ui/event_util_mac.mm b/atom/browser/ui/event_util_mac.mm new file mode 100644 index 000000000000..5226b155b74e --- /dev/null +++ b/atom/browser/ui/event_util_mac.mm @@ -0,0 +1,47 @@ +#include "atom/browser/ui/event_util.h" +#include "ui/base/accelerators/accelerator.h" + +namespace event_util { + bool isLeftButtonEvent(NSEvent* event) { + NSEventType type = [event type]; + return type == NSLeftMouseDown || + type == NSLeftMouseDragged || + type == NSLeftMouseUp; + } + + bool isRightButtonEvent(NSEvent* event) { + NSEventType type = [event type]; + return type == NSRightMouseDown || + type == NSRightMouseDragged || + type == NSRightMouseUp; + } + + bool isMiddleButtonEvent(NSEvent* event) { + if ([event buttonNumber] != 2) + return false; + + NSEventType type = [event type]; + return type == NSOtherMouseDown || + type == NSOtherMouseDragged || + type == NSOtherMouseUp; + } + + int EventFlagsFromNSEventWithModifiers(NSEvent* event, NSUInteger modifiers) { + int flags = 0; + flags |= (modifiers & NSAlphaShiftKeyMask) ? ui::EF_CAPS_LOCK_DOWN : 0; + flags |= (modifiers & NSShiftKeyMask) ? ui::EF_SHIFT_DOWN : 0; + flags |= (modifiers & NSControlKeyMask) ? ui::EF_CONTROL_DOWN : 0; + flags |= (modifiers & NSAlternateKeyMask) ? ui::EF_ALT_DOWN : 0; + flags |= (modifiers & NSCommandKeyMask) ? ui::EF_COMMAND_DOWN : 0; + flags |= isLeftButtonEvent(event) ? ui::EF_LEFT_MOUSE_BUTTON : 0; + flags |= isRightButtonEvent(event) ? ui::EF_RIGHT_MOUSE_BUTTON : 0; + flags |= isMiddleButtonEvent(event) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0; + return flags; + } + + // Retrieves a bitsum of ui::EventFlags from NSEvent. + int EventFlagsFromNSEvent(NSEvent* event) { + NSUInteger modifiers = [event modifierFlags]; + return EventFlagsFromNSEventWithModifiers(event, modifiers); + } +} // namespace event_util diff --git a/filenames.gypi b/filenames.gypi index ed51fc8fb47b..7d756e3beb7d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -170,6 +170,8 @@ 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/event_processing_window.h', 'atom/browser/ui/cocoa/event_processing_window.mm', + 'atom/browser/ui/event_util.h', + 'atom/browser/ui/event_util_mac.mm', 'atom/browser/ui/file_dialog.h', 'atom/browser/ui/file_dialog_gtk.cc', 'atom/browser/ui/file_dialog_mac.mm', From 74b45221950b03bbdcee1dbe84a604db33d415f6 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Mon, 27 Jul 2015 03:15:51 -0700 Subject: [PATCH 058/172] Add keyboard modifiers payload to tray click events * Add keyboard and mouse button bitsum to Tray click events payload * Move getBoundsFromRect: to common event_util file * Update documentation --- atom/browser/api/atom_api_tray.cc | 12 +++++------ atom/browser/api/atom_api_tray.h | 6 +++--- atom/browser/ui/event_util.h | 9 +++++--- atom/browser/ui/event_util_mac.mm | 32 ++++++++++++++++++++++------ atom/browser/ui/tray_icon.cc | 15 +++++++------ atom/browser/ui/tray_icon.h | 7 +++--- atom/browser/ui/tray_icon_cocoa.mm | 20 ++++++++--------- atom/browser/ui/tray_icon_observer.h | 6 +++--- docs/api/tray.md | 5 ++++- 9 files changed, 70 insertions(+), 42 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 82b2d01c613b..a849c03f59a0 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -40,12 +40,12 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { return new Tray(image); } -void Tray::OnClicked(const gfx::Rect& bounds) { - Emit("clicked", bounds); +void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { + Emit("clicked", bounds, modifiers); } -void Tray::OnDoubleClicked(const gfx::Rect& bounds) { - Emit("double-clicked", bounds); +void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) { + Emit("double-clicked", bounds, modifiers); } void Tray::OnBalloonShow() { @@ -60,8 +60,8 @@ void Tray::OnBalloonClosed() { Emit("balloon-closed"); } -void Tray::OnRightClicked(const gfx::Rect& bounds) { - Emit("right-clicked", bounds); +void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { + Emit("right-clicked", bounds, modifiers); } void Tray::OnDropFiles(const std::vector& files) { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index f3b91f00c0f0..10340677813f 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -42,12 +42,12 @@ class Tray : public mate::EventEmitter, virtual ~Tray(); // TrayIconObserver: - void OnClicked(const gfx::Rect& bounds) override; - void OnDoubleClicked(const gfx::Rect& bounds) override; + void OnClicked(const gfx::Rect& bounds, int modifiers) override; + void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override; void OnBalloonShow() override; void OnBalloonClicked() override; void OnBalloonClosed() override; - void OnRightClicked(const gfx::Rect& bounds) override; + void OnRightClicked(const gfx::Rect& bounds, int modifiers) override; void OnDropFiles(const std::vector& files) override; // mate::Wrappable: diff --git a/atom/browser/ui/event_util.h b/atom/browser/ui/event_util.h index 59a624d6bf96..b7278edaee82 100644 --- a/atom/browser/ui/event_util.h +++ b/atom/browser/ui/event_util.h @@ -2,16 +2,19 @@ #define ATOM_BROWSER_UI_EVENT_UTIL_H_ #import +#include "ui/gfx/geometry/rect.h" namespace event_util { -bool isLeftButtonEvent(NSEvent* event); -bool isRightButtonEvent(NSEvent* event); -bool isMiddleButtonEvent(NSEvent* event); +bool IsLeftButtonEvent(NSEvent* event); +bool IsRightButtonEvent(NSEvent* event); +bool IsMiddleButtonEvent(NSEvent* event); // Retrieves a bitsum of ui::EventFlags from NSEvent. int EventFlagsFromNSEvent(NSEvent* event); +gfx::Rect GetBoundsFromEvent(NSEvent* event); + } // namespace event_util #endif // ATOM_BROWSER_UI_EVENT_UTIL_H_ diff --git a/atom/browser/ui/event_util_mac.mm b/atom/browser/ui/event_util_mac.mm index 5226b155b74e..13188fdcf823 100644 --- a/atom/browser/ui/event_util_mac.mm +++ b/atom/browser/ui/event_util_mac.mm @@ -1,22 +1,24 @@ #include "atom/browser/ui/event_util.h" -#include "ui/base/accelerators/accelerator.h" + +#include "ui/events/event_constants.h" namespace event_util { - bool isLeftButtonEvent(NSEvent* event) { + + bool IsLeftButtonEvent(NSEvent* event) { NSEventType type = [event type]; return type == NSLeftMouseDown || type == NSLeftMouseDragged || type == NSLeftMouseUp; } - bool isRightButtonEvent(NSEvent* event) { + bool IsRightButtonEvent(NSEvent* event) { NSEventType type = [event type]; return type == NSRightMouseDown || type == NSRightMouseDragged || type == NSRightMouseUp; } - bool isMiddleButtonEvent(NSEvent* event) { + bool IsMiddleButtonEvent(NSEvent* event) { if ([event buttonNumber] != 2) return false; @@ -33,9 +35,9 @@ namespace event_util { flags |= (modifiers & NSControlKeyMask) ? ui::EF_CONTROL_DOWN : 0; flags |= (modifiers & NSAlternateKeyMask) ? ui::EF_ALT_DOWN : 0; flags |= (modifiers & NSCommandKeyMask) ? ui::EF_COMMAND_DOWN : 0; - flags |= isLeftButtonEvent(event) ? ui::EF_LEFT_MOUSE_BUTTON : 0; - flags |= isRightButtonEvent(event) ? ui::EF_RIGHT_MOUSE_BUTTON : 0; - flags |= isMiddleButtonEvent(event) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0; + flags |= IsLeftButtonEvent(event) ? ui::EF_LEFT_MOUSE_BUTTON : 0; + flags |= IsRightButtonEvent(event) ? ui::EF_RIGHT_MOUSE_BUTTON : 0; + flags |= IsMiddleButtonEvent(event) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0; return flags; } @@ -44,4 +46,20 @@ namespace event_util { NSUInteger modifiers = [event modifierFlags]; return EventFlagsFromNSEventWithModifiers(event, modifiers); } + + gfx::Rect GetBoundsFromEvent(NSEvent* event) { + NSRect frame = event.window.frame; + + gfx::Rect bounds( + frame.origin.x, + 0, + NSWidth(frame), + NSHeight(frame) + ); + + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); + return bounds; + } + } // namespace event_util diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index b22250d35c8f..d706d81868eb 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -29,12 +29,14 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon, void TrayIcon::PopContextMenu(const gfx::Point& pos) { } -void TrayIcon::NotifyClicked(const gfx::Rect& bounds) { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(bounds)); +void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, + OnClicked(bounds, modifiers)); } -void TrayIcon::NotifyDoubleClicked(const gfx::Rect& bounds) { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDoubleClicked(bounds)); +void TrayIcon::NotifyDoubleClicked(const gfx::Rect& bounds, int modifiers) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, + OnDoubleClicked(bounds, modifiers)); } void TrayIcon::NotifyBalloonShow() { @@ -49,8 +51,9 @@ void TrayIcon::NotifyBalloonClosed() { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnBalloonClosed()); } -void TrayIcon::NotifyRightClicked(const gfx::Rect& bounds) { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnRightClicked(bounds)); +void TrayIcon::NotifyRightClicked(const gfx::Rect& bounds, int modifiers) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, + OnRightClicked(bounds, modifiers)); } void TrayIcon::NotfiyDropFiles(const std::vector& files) { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 5e362806f5d6..a60622db9505 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -54,12 +54,13 @@ class TrayIcon { void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); } void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); } - void NotifyClicked(const gfx::Rect& = gfx::Rect()); - void NotifyDoubleClicked(const gfx::Rect& = gfx::Rect()); + void NotifyClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0); + void NotifyDoubleClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0); void NotifyBalloonShow(); void NotifyBalloonClicked(); void NotifyBalloonClosed(); - void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect()); + void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(), + int modifiers = 0); void NotfiyDropFiles(const std::vector& files); protected: diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 59386ff8eb41..3329619c99a7 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -5,6 +5,7 @@ #include "atom/browser/ui/tray_icon_cocoa.h" #include "atom/browser/ui/cocoa/atom_menu_controller.h" +#include "atom/browser/ui/event_util.h" #include "base/strings/sys_string_conversions.h" #include "ui/gfx/image/image.h" #include "ui/gfx/screen.h" @@ -147,16 +148,21 @@ const CGFloat kMargin = 3; return; } inMouseEventSequence_ = NO; + + // Single click if (event.clickCount == 1) { if (menuController_) { [statusItem_ popUpStatusItemMenu:[menuController_ menu]]; } - trayIcon_->NotifyClicked([self getBoundsFromEvent:event]); + trayIcon_->NotifyClicked(event_util::GetBoundsFromEvent(event), + event_util::EventFlagsFromNSEvent(event)); } + // Double click if (event.clickCount == 2 && !menuController_) { - trayIcon_->NotifyDoubleClicked([self getBoundsFromEvent:event]); + trayIcon_->NotifyDoubleClicked(event_util::GetBoundsFromEvent(event), + event_util::EventFlagsFromNSEvent(event)); } [self setNeedsDisplay:YES]; } @@ -173,7 +179,8 @@ const CGFloat kMargin = 3; } - (void)rightMouseUp:(NSEvent*)event { - trayIcon_->NotifyRightClicked([self getBoundsFromEvent:event]); + trayIcon_->NotifyRightClicked(event_util::GetBoundsFromEvent(event), + event_util::EventFlagsFromNSEvent(event)); } - (NSDragOperation)draggingEntered:(id )sender { @@ -199,13 +206,6 @@ const CGFloat kMargin = 3; return isHighlightEnable_ && (inMouseEventSequence_ || is_menu_open); } -- (gfx::Rect)getBoundsFromEvent:(NSEvent*)event { - NSRect frame = event.window.frame; - gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; - bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); - return bounds; -} @end namespace atom { diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index 474c6a771934..fa8090d7d6c5 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -16,12 +16,12 @@ namespace atom { class TrayIconObserver { public: - virtual void OnClicked(const gfx::Rect& bounds) {} - virtual void OnDoubleClicked(const gfx::Rect& bounds) {} + virtual void OnClicked(const gfx::Rect& bounds, int modifiers) {} + virtual void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {} virtual void OnBalloonShow() {} virtual void OnBalloonClicked() {} virtual void OnBalloonClosed() {} - virtual void OnRightClicked(const gfx::Rect& bounds) {} + virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {} virtual void OnDropFiles(const std::vector& files) {} protected: diff --git a/docs/api/tray.md b/docs/api/tray.md index 9332822a32a8..e35a43587331 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -53,6 +53,7 @@ Creates a new tray icon associated with the `image`. * `y` Integer * `width` Integer * `height` Integer +* [`modifiers`](https://code.google.com/p/chromium/codesearch#chromium/src/ui/events/event_constants.h&l=77) number - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is clicked. @@ -66,6 +67,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe * `y` Integer * `width` Integer * `height` Integer +* [`modifiers`](https://code.google.com/p/chromium/codesearch#chromium/src/ui/events/event_constants.h&l=77) number - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is right clicked. @@ -82,7 +84,8 @@ Emitted when the tray icon is double clicked. * `y` Integer * `width` Integer * `height` Integer - +* [`modifiers`](https://code.google.com/p/chromium/codesearch#chromium/src/ui/events/event_constants.h&l=77) number - bitsum of keyboard modifiers and mouse keys + __Note:__ This is only implemented on OS X. ### Event: 'balloon-show' From a44f14d76ef8d0444f4375f3773fecd36ad1c20c Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Mon, 27 Jul 2015 03:33:15 -0700 Subject: [PATCH 059/172] Fix code formatting issues --- atom/browser/ui/event_util.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/event_util.h b/atom/browser/ui/event_util.h index b7278edaee82..b5f9e7224d70 100644 --- a/atom/browser/ui/event_util.h +++ b/atom/browser/ui/event_util.h @@ -1,3 +1,7 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + #ifndef ATOM_BROWSER_UI_EVENT_UTIL_H_ #define ATOM_BROWSER_UI_EVENT_UTIL_H_ @@ -15,6 +19,6 @@ int EventFlagsFromNSEvent(NSEvent* event); gfx::Rect GetBoundsFromEvent(NSEvent* event); -} // namespace event_util +} // namespace event_util -#endif // ATOM_BROWSER_UI_EVENT_UTIL_H_ +#endif // ATOM_BROWSER_UI_EVENT_UTIL_H_ From 617bff8ec85b4717316d0fe8e258868e4f9f6e05 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 28 Jul 2015 10:30:36 +0800 Subject: [PATCH 060/172] Fix a missing the specified mime type check in accept attribute. --- atom/browser/web_dialog_helper.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index 93cb32cba7c7..a37d357d47dc 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -43,14 +43,15 @@ file_dialog::Filters GetFileTypesFromAcceptType( // Skip the first character. extensions.push_back(extension.substr(1)); } else { - if (ascii_type == "image/*" || ascii_type == "audio/*" || - ascii_type == "video/*") { - // For MIME Type - net::GetExtensionsForMimeType(ascii_type, &extensions); - } + // For MIME Type, `audio/*, vidio/*, image/* + net::GetExtensionsForMimeType(ascii_type, &extensions); } } + // If no valid exntesion is added, return empty filters. + if (extensions.empty()) + return filters; + filters.push_back(file_dialog::Filter()); for (const auto& extension : extensions) { #if defined(OS_WIN) From b10560a5b09cf6558d884f64b8d9fd218d4d9913 Mon Sep 17 00:00:00 2001 From: Jeffrey Morgan Date: Tue, 28 Jul 2015 16:51:41 +0100 Subject: [PATCH 061/172] Fix typo in auto-updater.md --- docs/api/auto-updater.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index a14e3ecd91f0..5274fc6c467e 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -107,7 +107,7 @@ Emitted when there is an error while updating. ## Event: checking-for-update -Emitted when checking for an update has started. +Emitted when checking if an update has started. ## Event: update-available From b08af8947384f101ee8587bbae166d57ab439961 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 11:22:12 +0800 Subject: [PATCH 062/172] Style fix for #2328 --- atom/browser/ui/win/notify_icon.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 6cf207d7b8e1..450fd0814044 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -28,20 +28,18 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, icon_id_(id), window_(window), message_id_(message), - menu_model_(NULL) { - + menu_model_(NULL), + has_tray_app_id_hash_(false) { // NB: If we have an App Model ID, we should propagate that to the tray. // Doing this prevents duplicate items from showing up in the notification // preferences (i.e. "Always Show / Show notifications only / etc") PWSTR explicit_app_id; - if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) { // GUIDs and MD5 hashes are the same length. So convenient! base::MD5Sum(explicit_app_id, - sizeof(wchar_t) * wcslen(explicit_app_id), - (base::MD5Digest*)&tray_app_id_hash_); + sizeof(wchar_t) * wcslen(explicit_app_id), + reinterpret_cast(&tray_app_id_hash_)); has_tray_app_id_hash_ = true; - CoTaskMemFree(explicit_app_id); } @@ -184,8 +182,8 @@ void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) { if (has_tray_app_id_hash_) { icon_data->uFlags |= NIF_GUID; memcpy(reinterpret_cast(&icon_data->guidItem), - &tray_app_id_hash_, - sizeof(GUID)); + &tray_app_id_hash_, + sizeof(GUID)); } } From 42ce91323c429d4f99eba5b44261e966f00a856c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 11:28:20 +0800 Subject: [PATCH 063/172] docs: Small style fix for #2337 --- docs/api/tray.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 9332822a32a8..dcb88dd4f75a 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -74,15 +74,15 @@ will be emitted if the tray icon has context menu. ### Event: 'double-clicked' -Emitted when the tray icon is double clicked. - * `event` * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer - + +Emitted when the tray icon is double clicked. + __Note:__ This is only implemented on OS X. ### Event: 'balloon-show' From 2c97cd64cf31b0284b0cf8731e063f118f9c8240 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 11:48:40 +0800 Subject: [PATCH 064/172] Minor style fix for #2352 --- atom/common/api/atom_api_native_image.cc | 1 + atom/common/api/atom_api_native_image_mac.mm | 2 +- docs/api/native-image.md | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index af173dda3e9a..ee9bb71a4d21 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -181,6 +181,7 @@ gfx::Size NativeImage::GetSize() { #if !defined(OS_MACOSX) void NativeImage::SetTemplateImage(bool setAsTemplate) { } + bool NativeImage::IsTemplateImage() { } #endif diff --git a/atom/common/api/atom_api_native_image_mac.mm b/atom/common/api/atom_api_native_image_mac.mm index a9e5225b815d..ad72d4b14924 100644 --- a/atom/common/api/atom_api_native_image_mac.mm +++ b/atom/common/api/atom_api_native_image_mac.mm @@ -15,7 +15,7 @@ void NativeImage::SetTemplateImage(bool setAsTemplate) { } bool NativeImage::IsTemplateImage() { - return [image_.AsNSImage() isTemplate]; + return [image_.AsNSImage() isTemplate]; } } // namespace api diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 5c6bf11659c5..aa2326da64e2 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -132,12 +132,12 @@ Returns the size of the image. [buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer -### NativeImage.isTemplateImage() - -Returns whether the image is a template image. - ### NativeImage.setTemplateImage(option) * `option` Boolean Marks the image as template image. + +### NativeImage.isTemplateImage() + +Returns whether the image is a template image. From 66553eea1ab39fd454b4ee3ca0c4cbdf24fa9c15 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 24 Jul 2015 15:09:11 +0530 Subject: [PATCH 065/172] webContents: api to add/remove path from devtools workspace --- atom/browser/api/atom_api_web_contents.cc | 19 +++++++++++ atom/browser/api/atom_api_web_contents.h | 8 +++-- atom/browser/common_web_contents_delegate.cc | 33 +++++++++++--------- atom/browser/common_web_contents_delegate.h | 5 +-- docs/api/browser-window.md | 12 +++++++ 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b79338548063..7070b7d6ebab 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -14,6 +14,7 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" #include "atom/common/event_emitter_caller.h" +#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" @@ -689,6 +690,22 @@ void WebContents::PrintToPDF(const base::DictionaryValue& setting, PrintToPDF(setting, callback); } +void WebContents::AddWorkSpace(const base::FilePath& path) { + if (path.empty()) { + node::ThrowError(isolate(), "path cannot be empty"); + return; + } + DevToolsAddFileSystem(path); +} + +void WebContents::RemoveWorkSpace(const base::FilePath& path) { + if (path.empty()) { + node::ThrowError(isolate(), "path cannot be empty"); + return; + } + DevToolsRemoveFileSystem(path); +} + void WebContents::Undo() { web_contents()->Undo(); } @@ -812,6 +829,8 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker) .SetMethod("print", &WebContents::Print) .SetMethod("_printToPDF", &WebContents::PrintToPDF) + .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) + .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetProperty("session", &WebContents::Session) .Build()); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1dcf5f4f6d29..68e0ad310529 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -37,8 +37,8 @@ class WebContents : public mate::TrackableObject, public content::WebContentsObserver { public: // For node.js callback function type: function(error, buffer) - typedef base::Callback, v8::Local)> - PrintToPDFCallback; + using PrintToPDFCallback = + base::Callback, v8::Local)>; // Create from an existing WebContents. static mate::Handle CreateFrom( @@ -83,6 +83,10 @@ class WebContents : public mate::TrackableObject, void PrintToPDF(const base::DictionaryValue& setting, const PrintToPDFCallback& callback); + // DevTools workspace api. + void AddWorkSpace(const base::FilePath& path); + void RemoveWorkSpace(const base::FilePath& path); + // Editing commands. void Undo(); void Redo(); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index af429929812a..3cef7c6d68cc 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -274,16 +274,21 @@ void CommonWebContentsDelegate::DevToolsAppendToFile( base::Unretained(this), url)); } -void CommonWebContentsDelegate::DevToolsAddFileSystem() { - file_dialog::Filters filters; - base::FilePath default_path; - std::vector paths; - int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; - if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path, - filters, flag, &paths)) - return; +void CommonWebContentsDelegate::DevToolsAddFileSystem( + const base::FilePath& file_system_path) { + base::FilePath path = file_system_path; + if (path.empty()) { + file_dialog::Filters filters; + base::FilePath default_path; + std::vector paths; + int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; + if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path, + filters, flag, &paths)) + return; + + path = paths[0]; + } - base::FilePath path = paths[0]; std::string registered_name; std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(), path, @@ -313,20 +318,20 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem() { } void CommonWebContentsDelegate::DevToolsRemoveFileSystem( - const std::string& file_system_path) { + const base::FilePath& file_system_path) { if (!web_contents_) return; - base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path); - storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path); + storage::IsolatedContext::GetInstance()-> + RevokeFileSystemByPath(file_system_path); for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it) - if (it->second == path) { + if (it->second == file_system_path) { saved_paths_.erase(it); break; } - base::StringValue file_system_path_value(file_system_path); + base::StringValue file_system_path_value(file_system_path.AsUTF8Unsafe()); web_contents_->CallClientFunction( "DevToolsAPI.fileSystemRemoved", &file_system_path_value, diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index 8c87548951b2..e21cd24e9107 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -80,8 +80,9 @@ class CommonWebContentsDelegate bool save_as) override; void DevToolsAppendToFile(const std::string& url, const std::string& content) override; - void DevToolsAddFileSystem() override; - void DevToolsRemoveFileSystem(const std::string& file_system_path) override; + void DevToolsAddFileSystem(const base::FilePath& path) override; + void DevToolsRemoveFileSystem( + const base::FilePath& file_system_path) override; private: // Callback for when DevToolsSaveToFile has completed. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index cee68183f783..cb4941daaa7f 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1042,6 +1042,18 @@ win.webContents.on("did-finish-load", function() { }); ``` +### WebContents.addWorkSpace(path) + +* `path` String + +Adds the specified path to devtools workspace. + +### WebContents.removeWorkSpace(path) + +* `path` String + +Removes the specified path from devtools workspace. + ### WebContents.send(channel[, args...]) * `channel` String From 9afa94f4b8a9f9ebe6ac3851f638bcfbd71ddc2e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:36:01 +0800 Subject: [PATCH 066/172] win: Implement double-clicked event --- atom/browser/ui/win/notify_icon.cc | 15 +++++++++------ atom/browser/ui/win/notify_icon.h | 4 +++- atom/browser/ui/win/notify_icon_host.cc | 7 ++++++- atom/common/api/atom_api_native_image.cc | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 450fd0814044..ed422b882a8f 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -63,7 +63,8 @@ NotifyIcon::~NotifyIcon() { } void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, - bool left_mouse_click) { + bool left_mouse_click, + bool double_button_click) { NOTIFYICONIDENTIFIER icon_id; memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER)); icon_id.uID = icon_id_; @@ -72,14 +73,16 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, RECT rect = { 0 }; Shell_NotifyIconGetRect(&icon_id, &rect); - // Pass to the observer if appropriate. if (left_mouse_click) { - NotifyClicked(gfx::Rect(rect)); + if (double_button_click) // double left click + NotifyDoubleClicked(gfx::Rect(rect)); + else // single left click + NotifyClicked(gfx::Rect(rect)); return; + } else if (!double_button_click) { // single right click + NotifyRightClicked(gfx::Rect(rect)); + PopContextMenu(cursor_pos); } - - NotifyRightClicked(gfx::Rect(rect)); - PopContextMenu(cursor_pos); } void NotifyIcon::ResetIcon() { diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 25ba8c8dc439..c004d5f39405 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -33,7 +33,9 @@ class NotifyIcon : public TrayIcon { // Handles a click event from the user - if |left_button_click| is true and // there is a registered observer, passes the click event to the observer, // otherwise displays the context menu if there is one. - void HandleClickEvent(const gfx::Point& cursor_pos, bool left_button_click); + void HandleClickEvent(const gfx::Point& cursor_pos, + bool left_button_click, + bool double_button_click); // Re-creates the status tray icon now after the taskbar has been created. void ResetIcon(); diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index 4aac629f248a..33ac722a5377 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -146,12 +146,17 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: case WM_CONTEXTMENU: // Walk our icons, find which one was clicked on, and invoke its // HandleClickEvent() method. gfx::Point cursor_pos( gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); - win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN); + win_icon->HandleClickEvent( + cursor_pos, + (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), + (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)); return TRUE; } } diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index ee9bb71a4d21..7819e314178c 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -183,6 +183,7 @@ void NativeImage::SetTemplateImage(bool setAsTemplate) { } bool NativeImage::IsTemplateImage() { + return false; } #endif From fc92ceb0b6cc7a56e8a3d3ff40fcad56ba4a81e0 Mon Sep 17 00:00:00 2001 From: Taichiro Yoshida Date: Wed, 29 Jul 2015 13:41:11 +0900 Subject: [PATCH 067/172] do not overwrite `node-integration` option If `node-integration` option pass to window.open, do not overwrite by current window's one --- atom/renderer/lib/override.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index 85914b116fd6..aea7feb3cbfe 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -61,7 +61,7 @@ window.open = (url, frameName='', features='') -> (options[name] = parseInt(options[name], 10) if options[name]?) for name in ints # Inherit the node-integration option of current window. - unless options['node-integration'] + unless options['node-integration']? for arg in process.argv when arg.indexOf('--node-integration=') is 0 options['node-integration'] = arg.substr(-4) is 'true' break From 15273c1f7ac10af886ade2e103fb83d12f4f4d9f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:41:40 +0800 Subject: [PATCH 068/172] docs: Don't say things that are expected --- docs/api/tray.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 47b5d7e3fed6..935430b7feaa 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -71,8 +71,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe Emitted when the tray icon is right clicked. -__Note:__ This is only implemented on OS X and Windows. On Windows, this event -will be emitted if the tray icon has context menu. +__Note:__ This is only implemented on OS X and Windows. ### Event: 'double-clicked' @@ -86,7 +85,7 @@ will be emitted if the tray icon has context menu. Emitted when the tray icon is double clicked. -__Note:__ This is only implemented on OS X. +__Note:__ This is only implemented on OS X and Windows. ### Event: 'balloon-show' @@ -171,9 +170,10 @@ __Note:__ This is only implemented on Windows. * `x` Integer * `y` Integer -__Note:__ This is only implemented on OS X and Windows. The `position` is only available on Windows, and it is (0, 0) by default. +__Note:__ This is only implemented on OS X and Windows. + ### Tray.setContextMenu(menu) * `menu` Menu From 74248253f591ca20b42a154bf39225f747a0fd3a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 12:55:44 +0800 Subject: [PATCH 069/172] win: Set GUID when getting icon's bounds --- atom/browser/ui/win/notify_icon.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index ed422b882a8f..b58b5931276c 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -70,6 +70,11 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, icon_id.uID = icon_id_; icon_id.hWnd = window_; icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER); + if (has_tray_app_id_hash_) + memcpy(reinterpret_cast(&icon_id.guidItem), + &tray_app_id_hash_, + sizeof(GUID)); + RECT rect = { 0 }; Shell_NotifyIconGetRect(&icon_id, &rect); From d42fd6fc7ee307d6a463c4f52e7acf9e78f54a3d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 13:10:51 +0800 Subject: [PATCH 070/172] win: Pass modifers in 'clicked' events --- atom/browser/ui/win/notify_icon.cc | 7 ++++--- atom/browser/ui/win/notify_icon.h | 1 + atom/browser/ui/win/notify_icon_host.cc | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index b58b5931276c..fd9a90ae1d5d 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -63,6 +63,7 @@ NotifyIcon::~NotifyIcon() { } void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, + int modifiers, bool left_mouse_click, bool double_button_click) { NOTIFYICONIDENTIFIER icon_id; @@ -80,12 +81,12 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, if (left_mouse_click) { if (double_button_click) // double left click - NotifyDoubleClicked(gfx::Rect(rect)); + NotifyDoubleClicked(gfx::Rect(rect), modifiers); else // single left click - NotifyClicked(gfx::Rect(rect)); + NotifyClicked(gfx::Rect(rect), modifiers); return; } else if (!double_button_click) { // single right click - NotifyRightClicked(gfx::Rect(rect)); + NotifyRightClicked(gfx::Rect(rect), modifiers); PopContextMenu(cursor_pos); } } diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index c004d5f39405..a28a00ff0d6a 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -34,6 +34,7 @@ class NotifyIcon : public TrayIcon { // there is a registered observer, passes the click event to the observer, // otherwise displays the context menu if there is one. void HandleClickEvent(const gfx::Point& cursor_pos, + int modifiers, bool left_button_click, bool double_button_click); diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index 33ac722a5377..c34e14375e76 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -11,7 +11,9 @@ #include "base/stl_util.h" #include "base/threading/non_thread_safe.h" #include "base/threading/thread.h" +#include "base/win/win_util.h" #include "base/win/wrapped_window_proc.h" +#include "ui/events/event_constants.h" #include "ui/gfx/screen.h" #include "ui/gfx/win/hwnd_util.h" @@ -26,6 +28,17 @@ const UINT kBaseIconId = 2; const wchar_t kNotifyIconHostWindowClass[] = L"Electron_NotifyIconHostWindow"; +int GetKeyboardModifers() { + int modifiers = ui::EF_NONE; + if (base::win::IsShiftPressed()) + modifiers |= ui::EF_SHIFT_DOWN; + if (base::win::IsCtrlPressed()) + modifiers |= ui::EF_CONTROL_DOWN; + if (base::win::IsAltPressed()) + modifiers |= ui::EF_ALT_DOWN; + return modifiers; +} + } // namespace NotifyIconHost::NotifyIconHost() @@ -155,6 +168,7 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); win_icon->HandleClickEvent( cursor_pos, + GetKeyboardModifers(), (lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK), (lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)); return TRUE; From 45f5a10d5df6a950fff69e58e224b7dcf3bfa95b Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 13:27:07 +0800 Subject: [PATCH 071/172] Use NSImageView to draw tray icon. * Fixes Tempate image doesn't show correctly in dark mode. * Fixes the tray icon is stretched showing in menubar. * Fixes title color will not reversed in dark mode. --- atom/browser/ui/tray_icon_cocoa.mm | 73 ++++++++++++++++++------------ 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 0f5a768e5d59..c4f3975afedb 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -12,8 +12,8 @@ namespace { -const CGFloat kStatusItemLength = 26; -const CGFloat kMargin = 3; +// By default, OS X sets 4px to tray image as left and right padding margin. +const CGFloat kHorizontalMargin = 4; } // namespace @@ -24,6 +24,7 @@ const CGFloat kMargin = 3; BOOL inMouseEventSequence_; base::scoped_nsobject image_; base::scoped_nsobject alternateImage_; + base::scoped_nsobject image_view_; base::scoped_nsobject title_; base::scoped_nsobject statusItem_; } @@ -37,11 +38,17 @@ const CGFloat kMargin = 3; isHighlightEnable_ = YES; statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength: NSVariableStatusItemLength] retain]); + CGFloat itemLength = [[statusItem_ statusBar] thickness]; NSRect frame = NSMakeRect(0, 0, - kStatusItemLength, - [[statusItem_ statusBar] thickness]); + itemLength, + itemLength); if ((self = [super initWithFrame:frame])) { + image_view_.reset([[[NSImageView alloc] initWithFrame:frame] retain]); + // Unregister image_view_ as a dragged destination, allows its parent view + // (StatusItemView) handle dragging events. + [image_view_ unregisterDraggedTypes]; + [self addSubview:image_view_]; [self registerForDraggedTypes: [NSArray arrayWithObjects:NSFilenamesPboardType, nil]]; [statusItem_ setView:self]; @@ -55,44 +62,53 @@ const CGFloat kMargin = 3; } - (void)drawRect:(NSRect)dirtyRect { - // Draw the tray icon and title that align with NSSStatusItem, layout: + // Draw the tray icon and title that align with NSStatusItem, layout: // ---------------- // | icon | title | /// ---------------- BOOL highlight = [self shouldHighlight]; CGFloat titleWidth = [self titleWidth]; - // Calculate the total icon bounds. + CGFloat statusItemHeight = [[statusItem_ statusBar] thickness]; + CGFloat iconWidth =((highlight && alternateImage_) ? + [alternateImage_ size].width : [image_ size].width) + + 2 * kHorizontalMargin; + NSRect iconRect = NSMakeRect(0, 0, iconWidth, statusItemHeight); + + // Calculate the total status item bounds. + CGFloat statusItemWidth = iconWidth + titleWidth; + // If title is set, need to add right margin to the title. + if (title_) { + statusItemWidth += kHorizontalMargin; + } NSRect statusItemBounds = NSMakeRect(0, 0, - kStatusItemLength + titleWidth, - [[statusItem_ statusBar] thickness]); + statusItemWidth, + statusItemHeight); [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds withHighlight:highlight]; - [statusItem_ setLength:titleWidth + kStatusItemLength]; + [statusItem_ setLength:statusItemWidth]; + + // Custom ImageView + [image_view_ setFrame: iconRect]; + if (highlight && alternateImage_) { + [image_view_ setImage:alternateImage_]; + } else { + [image_view_ setImage:image_]; + } + if (title_) { - NSRect titleDrawRect = NSMakeRect(kStatusItemLength, + NSRect titleDrawRect = NSMakeRect(iconWidth, 0, - titleWidth + kStatusItemLength, - [[statusItem_ statusBar] thickness]); + statusItemWidth - kHorizontalMargin, + statusItemHeight); [title_ drawInRect:titleDrawRect withAttributes:[self titleAttributes]]; } +} - NSRect iconRect = NSMakeRect(0, - 0, - kStatusItemLength, - [[statusItem_ statusBar] thickness]); - if (highlight && alternateImage_) { - [alternateImage_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin) - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1]; - } else { - [image_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin) - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1]; - } +- (BOOL) isDarkMode { + return [[[NSAppearance currentAppearance] name] hasPrefix: + NSAppearanceNameVibrantDark]; } - (CGFloat)titleWidth { @@ -105,7 +121,8 @@ const CGFloat kMargin = 3; - (NSDictionary*)titleAttributes { NSFont* font = [NSFont menuBarFontOfSize:0]; - NSColor* foregroundColor = [NSColor blackColor]; + NSColor* foregroundColor = + [self isDarkMode] ? [NSColor whiteColor] : [NSColor blackColor]; return [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName, From 877830e4a1159f7bd31eb0c91b6859a3d7cb351f Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 14:03:07 +0800 Subject: [PATCH 072/172] No need for default_download_path_ member. --- atom/browser/atom_browser_context.h | 2 +- atom/browser/atom_download_manager_delegate.cc | 8 ++++---- atom/browser/atom_download_manager_delegate.h | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 3455916fa5b3..c1ff613b8c07 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -32,7 +32,7 @@ class AtomBrowserContext : public brightray::BrowserContext { content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; - // brightray::BrowserContext:: + // brightray::BrowserContext: void RegisterPrefs(PrefRegistrySimple* pref_registry) override; AtomURLRequestJobFactory* job_factory() const { return job_factory_; } diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index 7e393f7d2c21..b573a396332f 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -102,12 +102,12 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget( AtomBrowserContext* browser_context = static_cast( download_manager_->GetBrowserContext()); - default_download_path_ = browser_context->prefs()->GetFilePath( + base::FilePath default_download_path = browser_context->prefs()->GetFilePath( prefs::kDownloadDefaultDirectory); // If users didn't set download path, use 'Downloads' directory by default. - if (default_download_path_.empty()) { + if (default_download_path.empty()) { auto path = download_manager_->GetBrowserContext()->GetPath(); - default_download_path_ = path.Append(FILE_PATH_LITERAL("Downloads")); + default_download_path = path.Append(FILE_PATH_LITERAL("Downloads")); } if (!download->GetForcedFilePath().empty()) { @@ -131,7 +131,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget( download->GetContentDisposition(), download->GetSuggestedFilename(), download->GetMimeType(), - default_download_path_, + default_download_path, download_path_callback)); return true; } diff --git a/atom/browser/atom_download_manager_delegate.h b/atom/browser/atom_download_manager_delegate.h index e2d829243299..2df3a7d45a6b 100644 --- a/atom/browser/atom_download_manager_delegate.h +++ b/atom/browser/atom_download_manager_delegate.h @@ -47,7 +47,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate { private: content::DownloadManager* download_manager_; - base::FilePath default_download_path_; base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate); From f40155645c4a1c60d00db5dc248575d9b78153d8 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 14:13:28 +0800 Subject: [PATCH 073/172] :memo: say more about setDownloadPath API. --- docs/api/browser-window.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 766b9ce92439..b1c670a34a8b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1224,3 +1224,6 @@ proxy-uri = ["://"][":"] ### Session.setDownloadPath(path) * `path` String - The download location + +Sets download saving directory. By default, the download directory will be the +`Downloads` under the respective app folder. From 625143426a23507e7fb70714d29314b2f8a17bca Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:24:45 +0800 Subject: [PATCH 074/172] Enable using custom events when emitting --- atom/browser/api/event_emitter.cc | 13 ++++++++++--- atom/browser/api/event_emitter.h | 28 +++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/event_emitter.cc b/atom/browser/api/event_emitter.cc index 7337830780f5..aa0b6c8781a3 100644 --- a/atom/browser/api/event_emitter.cc +++ b/atom/browser/api/event_emitter.cc @@ -37,9 +37,8 @@ v8::Local CreateEventObject(v8::Isolate* isolate) { EventEmitter::EventEmitter() { } -v8::Local EventEmitter::CreateJSEvent(v8::Isolate* isolate, - content::WebContents* sender, - IPC::Message* message) { +v8::Local EventEmitter::CreateJSEvent( + v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) { v8::Local event; bool use_native_event = sender && message; @@ -54,4 +53,12 @@ v8::Local EventEmitter::CreateJSEvent(v8::Isolate* isolate, return event; } +v8::Local EventEmitter::CreateCustomEvent( + v8::Isolate* isolate, v8::Local custom_event) { + v8::Local event = CreateEventObject(isolate); + event->SetPrototype(custom_event->CreationContext(), custom_event); + mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); + return event; +} + } // namespace mate diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 6910df3a28d0..178c61d853ca 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -25,6 +25,14 @@ class EventEmitter : public Wrappable { public: typedef std::vector> ValueArray; + // this.emit(name, event, args...); + template + bool EmitCustomEvent(const base::StringPiece& name, + v8::Local event, + const Args&... args) { + return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...); + } + // this.emit(name, new Event(), args...); template bool Emit(const base::StringPiece& name, const Args&... args) { @@ -37,21 +45,31 @@ class EventEmitter : public Wrappable { content::WebContents* sender, IPC::Message* message, const Args&... args) { - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); v8::Local event = CreateJSEvent(isolate(), sender, message); - EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); - return event->Get( - StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); + return EmitWithEvent(name, event, args...); } protected: EventEmitter(); private: + // this.emit(name, event, args...); + template + bool EmitWithEvent(const base::StringPiece& name, + v8::Local event, + const Args&... args) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); + return event->Get( + StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); + } + v8::Local CreateJSEvent(v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message); + v8::Local CreateCustomEvent( + v8::Isolate* isolate, v8::Local event); DISALLOW_COPY_AND_ASSIGN(EventEmitter); }; From 8d22eeb3be7ce0b4d6c1393cf686f63fa3aa21c1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:25:12 +0800 Subject: [PATCH 075/172] Use DOM's way of telling modifiers --- atom/browser/api/atom_api_tray.cc | 31 +++++++++++++++++++++++++------ atom/browser/api/atom_api_tray.h | 4 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index a849c03f59a0..82f78519aeb3 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -14,6 +14,7 @@ #include "atom/common/native_mate_converters/string16_converter.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" +#include "ui/events/event_constants.h" #include "ui/gfx/image/image.h" #include "atom/common/node_includes.h" @@ -41,11 +42,24 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { } void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { - Emit("clicked", bounds, modifiers); + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("clicked", + ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) { - Emit("double-clicked", bounds, modifiers); + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("double-clicked", + ModifiersToObject(isolate(), modifiers), bounds); +} + +void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + EmitCustomEvent("right-clicked", + ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnBalloonShow() { @@ -60,10 +74,6 @@ void Tray::OnBalloonClosed() { Emit("balloon-closed"); } -void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { - Emit("right-clicked", bounds, modifiers); -} - void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } @@ -120,6 +130,15 @@ void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) { tray_icon_->SetContextMenu(menu->model()); } +v8::Local Tray::ModifiersToObject(v8::Isolate* isolate, + int modifiers) { + mate::Dictionary obj(isolate, v8::Object::New(isolate)); + obj.Set("shiftKey", static_cast(modifiers & ui::EF_SHIFT_DOWN)); + obj.Set("ctrlKey", static_cast(modifiers & ui::EF_CONTROL_DOWN)); + obj.Set("altKey", static_cast(modifiers & ui::EF_ALT_DOWN)); + return obj.GetHandle(); +} + // static void Tray::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 10340677813f..02f7418fe41d 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -44,10 +44,10 @@ class Tray : public mate::EventEmitter, // TrayIconObserver: void OnClicked(const gfx::Rect& bounds, int modifiers) override; void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override; + void OnRightClicked(const gfx::Rect& bounds, int modifiers) override; void OnBalloonShow() override; void OnBalloonClicked() override; void OnBalloonClosed() override; - void OnRightClicked(const gfx::Rect& bounds, int modifiers) override; void OnDropFiles(const std::vector& files) override; // mate::Wrappable: @@ -64,6 +64,8 @@ class Tray : public mate::EventEmitter, void SetContextMenu(mate::Arguments* args, Menu* menu); private: + v8::Local ModifiersToObject(v8::Isolate* isolate, int modifiers); + scoped_ptr tray_icon_; DISALLOW_COPY_AND_ASSIGN(Tray); From 3e1a5b229ce2750182ec1ac1070142d73dd03d02 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:27:32 +0800 Subject: [PATCH 076/172] docs: modifiers removed --- docs/api/tray.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 935430b7feaa..5c8c88018f71 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -47,13 +47,15 @@ Creates a new tray icon associated with the `image`. ### Event: 'clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is clicked. @@ -61,13 +63,15 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe ### Event: 'right-clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is right clicked. @@ -75,13 +79,15 @@ __Note:__ This is only implemented on OS X and Windows. ### Event: 'double-clicked' -* `event` +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer * `width` Integer * `height` Integer -* [`modifiers`][modifiers] Integer - bitsum of keyboard modifiers and mouse keys Emitted when the tray icon is double clicked. @@ -181,4 +187,3 @@ __Note:__ This is only implemented on OS X and Windows. Sets the context menu for this icon. [event-emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter -[modifiers]: https://code.google.com/p/chromium/codesearch#chromium/src/ui/events/event_constants.h&l=77 From b2f03fc2d878061d3c001dbc2cb21676db6e35fd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:44:08 +0800 Subject: [PATCH 077/172] Add metaKey --- atom/browser/api/atom_api_tray.cc | 1 + atom/browser/ui/win/notify_icon_host.cc | 8 ++++++++ docs/api/tray.md | 3 +++ 3 files changed, 12 insertions(+) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 82f78519aeb3..0f07737da2bf 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -136,6 +136,7 @@ v8::Local Tray::ModifiersToObject(v8::Isolate* isolate, obj.Set("shiftKey", static_cast(modifiers & ui::EF_SHIFT_DOWN)); obj.Set("ctrlKey", static_cast(modifiers & ui::EF_CONTROL_DOWN)); obj.Set("altKey", static_cast(modifiers & ui::EF_ALT_DOWN)); + obj.Set("metaKey", static_cast(modifiers & ui::EF_COMMAND_DOWN)); return obj.GetHandle(); } diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index c34e14375e76..2c84837e714d 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -5,6 +5,7 @@ #include "atom/browser/ui/win/notify_icon_host.h" #include +#include #include "atom/browser/ui/win/notify_icon.h" #include "base/bind.h" @@ -28,6 +29,11 @@ const UINT kBaseIconId = 2; const wchar_t kNotifyIconHostWindowClass[] = L"Electron_NotifyIconHostWindow"; +bool IsWinPressed() { + return ((::GetKeyState(VK_LWIN) & 0x8000) == 0x8000) || + ((::GetKeyState(VK_RWIN) & 0x8000) == 0x8000); +} + int GetKeyboardModifers() { int modifiers = ui::EF_NONE; if (base::win::IsShiftPressed()) @@ -36,6 +42,8 @@ int GetKeyboardModifers() { modifiers |= ui::EF_CONTROL_DOWN; if (base::win::IsAltPressed()) modifiers |= ui::EF_ALT_DOWN; + if (IsWinPressed()) + modifiers |= ui::EF_COMMAND_DOWN; return modifiers; } diff --git a/docs/api/tray.md b/docs/api/tray.md index 5c8c88018f71..3d3ebc280f5a 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -51,6 +51,7 @@ Creates a new tray icon associated with the `image`. * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer @@ -67,6 +68,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newe * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer @@ -83,6 +85,7 @@ __Note:__ This is only implemented on OS X and Windows. * `altKey` Boolean * `shiftKey` Boolean * `ctrlKey` Boolean + * `metaKey` Boolean * `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer From b786772819b0e2dd8d9038441a3bb0c39982cc26 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 14:50:56 +0800 Subject: [PATCH 078/172] Update brightray for #2324 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 1c79219c5c8e..84a41fb634a9 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 1c79219c5c8e8636208f1aaf2c937d11acba34ea +Subproject commit 84a41fb634a96699f34c6ba0b15b8d5c8faf82e6 From 77a8a3d33c952acf169417e820b114103a332066 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 16:09:32 +0800 Subject: [PATCH 079/172] Add `allow-running-insecure-content`, `allow-display-insecure-content` in BrowserWindow option. --- atom/browser/native_window.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c03ab1ac24a4..ca5df45d1782 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -434,6 +434,10 @@ void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) { prefs->experimental_webgl_enabled = b; if (web_preferences_.Get("webaudio", &b)) prefs->webaudio_enabled = b; + if (web_preferences_.Get("allow-displaying-insecure-content", &b)) + prefs->allow_displaying_insecure_content = b; + if (web_preferences_.Get("allow-running-insecure-content", &b)) + prefs->allow_running_insecure_content = b; if (web_preferences_.Get("web-security", &b)) { prefs->web_security_enabled = b; prefs->allow_displaying_insecure_content = !b; From 1d0568dd5b73b06326831d6866f94240521ace5c Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 16:15:16 +0800 Subject: [PATCH 080/172] :memo: `allow-running-insecure-content` and `allow-displaying-insecure-content`. --- docs/api/browser-window.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index cee68183f783..b6f254460763 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -76,7 +76,15 @@ You can also create a window without chrome by using textured window. Defaults to `true`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean - * `web-security` Boolean + * `web-security` Boolean - When setting `false`, it will disable the same-origin + policy(Ususally using testing websites by people) and set `allow_displaying_insecure_content` + and `allow_running_insecure_content` to `true`. + * `allow-displaying-insecure-content` Boolean - Allow a https page to display + content like image from http URLs. This option will be overrided to `true` + when `web-security` option is set. + * `allow-running-insecure-content` Boolean - Allow a https page to run JavaScript, + CSS or plugins from http URLs. This option will be overrided to `true` when + `web-security` option is set. * `images` Boolean * `java` Boolean * `text-areas-are-resizable` Boolean From b311969f0e8275a1c0414066a0481ff77a274277 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 17:16:23 +0800 Subject: [PATCH 081/172] Update brightray for #2327 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 84a41fb634a9..956ee8a3296f 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 84a41fb634a96699f34c6ba0b15b8d5c8faf82e6 +Subproject commit 956ee8a3296f2ea8eaf48b6d6c9bbb7ba26d4c1a From f154da38e6f9f2299b95981e831fe08533bc69e6 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 18:07:06 +0800 Subject: [PATCH 082/172] Make 'allow-displaying-insecure-content' and 'allow-running-insecure-content' higher priority than `web-security`. --- atom/browser/native_window.cc | 8 ++++---- docs/api/browser-window.md | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index ca5df45d1782..ac3efc604e07 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -434,15 +434,15 @@ void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) { prefs->experimental_webgl_enabled = b; if (web_preferences_.Get("webaudio", &b)) prefs->webaudio_enabled = b; - if (web_preferences_.Get("allow-displaying-insecure-content", &b)) - prefs->allow_displaying_insecure_content = b; - if (web_preferences_.Get("allow-running-insecure-content", &b)) - prefs->allow_running_insecure_content = b; if (web_preferences_.Get("web-security", &b)) { prefs->web_security_enabled = b; prefs->allow_displaying_insecure_content = !b; prefs->allow_running_insecure_content = !b; } + if (web_preferences_.Get("allow-displaying-insecure-content", &b)) + prefs->allow_displaying_insecure_content = b; + if (web_preferences_.Get("allow-running-insecure-content", &b)) + prefs->allow_running_insecure_content = b; if (web_preferences_.Get("extra-plugin-dirs", &list)) { if (content::PluginService::GetInstance()->NPAPIPluginsSupported()) { for (size_t i = 0; i < list.size(); ++i) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index b6f254460763..f8830632caa6 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -77,14 +77,13 @@ You can also create a window without chrome by using * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean - When setting `false`, it will disable the same-origin - policy(Ususally using testing websites by people) and set `allow_displaying_insecure_content` - and `allow_running_insecure_content` to `true`. + policy(Usually using testing websites by people), and set `allow_displaying_insecure_content` + and `allow_running_insecure_content` to `true` if these two options are not + set by user. * `allow-displaying-insecure-content` Boolean - Allow a https page to display - content like image from http URLs. This option will be overrided to `true` - when `web-security` option is set. + content like image from http URLs. * `allow-running-insecure-content` Boolean - Allow a https page to run JavaScript, - CSS or plugins from http URLs. This option will be overrided to `true` when - `web-security` option is set. + CSS or plugins from http URLs. * `images` Boolean * `java` Boolean * `text-areas-are-resizable` Boolean From 643ed27fd4c92c3715dc3df441ad157fc16ad9fd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Jul 2015 18:26:20 +0800 Subject: [PATCH 083/172] Check whether entry is null This fixes the crash in #7877. --- atom/browser/native_window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c03ab1ac24a4..8bf25dce9e3f 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -549,7 +549,7 @@ void NativeWindow::BeforeUnloadDialogCancelled() { void NativeWindow::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { bool prevent_default = false; - std::string text = base::UTF16ToUTF8(entry->GetTitle()); + std::string text = entry ? base::UTF16ToUTF8(entry->GetTitle()) : ""; FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnPageTitleUpdated(&prevent_default, text)); From f9d59155425ae7f8111c4c861a4d49a99d36a00f Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Wed, 29 Jul 2015 13:45:30 +0100 Subject: [PATCH 084/172] more accuracy around why to use ASAR 'protect' implies a lot more security than ASAR provides (none). I asked around #2374 to get some understanding of what ASAR does do for you. --- docs/tutorial/application-packaging.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index 0741b2572447..7568204fb62f 100644 --- a/docs/tutorial/application-packaging.md +++ b/docs/tutorial/application-packaging.md @@ -1,6 +1,6 @@ # Application packaging -To protect your app's resources and source code from the users, you can choose +To mitigate [issues](https://github.com/joyent/node/issues/6960) around long path names on Windows, slightly speed up `require` and conceal your source code from cursory inspection you can choose to package your app into an [asar][asar] archive with little changes to your source code. @@ -161,3 +161,4 @@ After running the command, apart from the `app.asar`, there is also an should copy it together with `app.asar` when shipping it to users. [asar]: https://github.com/atom/asar + From 90bd32c6800bbb7cd20a4c1fe8a1fe7e781ca104 Mon Sep 17 00:00:00 2001 From: Vivek Patel Date: Wed, 29 Jul 2015 15:04:34 +0200 Subject: [PATCH 085/172] Replaced 'browser' with 'main' "A JavaScript error occured in the browser process" is confusing. Replacing it with 'main', just like everywhere else. --- atom/browser/lib/init.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 678d7422b0c6..e61323bfdcc0 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -38,7 +38,7 @@ process.on 'uncaughtException', (error) -> # Show error in GUI. stack = error.stack ? "#{error.name}: #{error.message}" message = "Uncaught Exception:\n#{stack}" - require('dialog').showErrorBox 'A JavaScript error occured in the browser process', message + require('dialog').showErrorBox 'A JavaScript error occured in the main process', message # Emit 'exit' event on quit. app = require 'app' From 8d09f13bad57012b007641b9103dfb3f61c56fb9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jul 2015 10:27:34 +0800 Subject: [PATCH 086/172] Fix running callback when global.global is deleted Close #2366. --- atom/common/api/lib/callbacks-registry.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index b549d17c7285..4999e19dc119 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -1,3 +1,5 @@ +global = global # the "global.global" might be deleted later + module.exports = class CallbacksRegistry constructor: -> From 2d5c0ac9eebb5bf37de1dcb3375511d6dd6afbab Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jul 2015 10:31:49 +0800 Subject: [PATCH 087/172] Coffeescript declares variable before assigning it --- atom/common/api/lib/callbacks-registry.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index 4999e19dc119..8f5eb62916c0 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -1,4 +1,4 @@ -global = global # the "global.global" might be deleted later +savedGlobal = global # the "global.global" might be deleted later module.exports = class CallbacksRegistry @@ -18,10 +18,10 @@ class CallbacksRegistry @callbacks[id] ? -> call: (id, args...) -> - @get(id).call global, args... + @get(id).call savedGlobal, args... apply: (id, args...) -> - @get(id).apply global, args... + @get(id).apply savedGlobal, args... remove: (id) -> delete @callbacks[id] From 0e779e20c3fbf79bb37609a5257a5c87b9a18503 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jul 2015 10:38:04 +0800 Subject: [PATCH 088/172] Fix compilation error caused by #2340 --- atom/browser/api/atom_api_session.cc | 7 ++++--- atom/browser/api/atom_api_session.h | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index c864598a3191..19efd2d32ac8 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -10,6 +10,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/atom_browser_context.h" #include "atom/common/native_mate_converters/gurl_converter.h" +#include "atom/common/native_mate_converters/file_path_converter.h" #include "base/files/file_path.h" #include "base/prefs/pref_service.h" #include "base/strings/string_util.h" @@ -254,9 +255,9 @@ void Session::SetProxy(const std::string& proxy, base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback)); } -void Session::SetDownloadPath(const std::string& path) { - browser_context_->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory, - base::FilePath(path)); +void Session::SetDownloadPath(const base::FilePath& path) { + browser_context_->prefs()->SetFilePath( + prefs::kDownloadDefaultDirectory, path); } v8::Local Session::Cookies(v8::Isolate* isolate) { diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index a8c0e2444955..bd12b7589914 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -17,6 +17,10 @@ namespace mate { class Arguments; } +namespace base { +class FilePath; +} + namespace atom { class AtomBrowserContext; @@ -46,7 +50,7 @@ class Session: public mate::TrackableObject { void ClearCache(const net::CompletionCallback& callback); void ClearStorageData(mate::Arguments* args); void SetProxy(const std::string& proxy, const base::Closure& callback); - void SetDownloadPath(const std::string& path); + void SetDownloadPath(const base::FilePath& path); v8::Local Cookies(v8::Isolate* isolate); v8::Global cookies_; From be24d3e78ce9e887b7fa88bf8b3106fb9705c494 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jul 2015 11:57:34 +0800 Subject: [PATCH 089/172] mac: Make the tray icon behave more like the official one --- atom/browser/ui/tray_icon_cocoa.mm | 162 ++++++++++++++++++----------- 1 file changed, 104 insertions(+), 58 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index c4f3975afedb..055ac12c4046 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -14,6 +14,8 @@ namespace { // By default, OS X sets 4px to tray image as left and right padding margin. const CGFloat kHorizontalMargin = 4; +// OS X tends to make the title 2px lower. +const CGFloat kVerticalTitleMargin = 2; } // namespace @@ -33,24 +35,33 @@ const CGFloat kHorizontalMargin = 4; @implementation StatusItemView -- (id)initWithIcon:(atom::TrayIconCocoa*)icon { +- (id)initWithImage:(NSImage*)image icon:(atom::TrayIconCocoa*)icon { + image_.reset([image copy]); trayIcon_ = icon; isHighlightEnable_ = YES; - statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength: - NSVariableStatusItemLength] retain]); - CGFloat itemLength = [[statusItem_ statusBar] thickness]; - NSRect frame = NSMakeRect(0, - 0, - itemLength, - itemLength); + + // Get the initial size. + NSStatusBar* statusBar = [NSStatusBar systemStatusBar]; + NSRect frame = NSMakeRect(0, 0, [self fullWidth], [statusBar thickness]); + if ((self = [super initWithFrame:frame])) { - image_view_.reset([[[NSImageView alloc] initWithFrame:frame] retain]); + // Setup the image view. + NSRect iconFrame = frame; + iconFrame.size.width = [self iconWidth]; + image_view_.reset([[NSImageView alloc] initWithFrame:iconFrame]); + [image_view_ setImageScaling:NSImageScaleNone]; + [image_view_ setImageAlignment:NSImageAlignCenter]; + [self addSubview:image_view_]; + // Unregister image_view_ as a dragged destination, allows its parent view // (StatusItemView) handle dragging events. [image_view_ unregisterDraggedTypes]; - [self addSubview:image_view_]; - [self registerForDraggedTypes: - [NSArray arrayWithObjects:NSFilenamesPboardType, nil]]; + NSArray* types = [NSArray arrayWithObjects:NSFilenamesPboardType, nil]; + [self registerForDraggedTypes:types]; + + // Create the status item. + statusItem_.reset([[[NSStatusBar systemStatusBar] + statusItemWithLength:NSWidth(frame)] retain]); [statusItem_ setView:self]; } return self; @@ -66,68 +77,94 @@ const CGFloat kHorizontalMargin = 4; // ---------------- // | icon | title | /// ---------------- - BOOL highlight = [self shouldHighlight]; - CGFloat titleWidth = [self titleWidth]; - CGFloat statusItemHeight = [[statusItem_ statusBar] thickness]; - CGFloat iconWidth =((highlight && alternateImage_) ? - [alternateImage_ size].width : [image_ size].width) + - 2 * kHorizontalMargin; - NSRect iconRect = NSMakeRect(0, 0, iconWidth, statusItemHeight); - // Calculate the total status item bounds. - CGFloat statusItemWidth = iconWidth + titleWidth; - // If title is set, need to add right margin to the title. - if (title_) { - statusItemWidth += kHorizontalMargin; - } - NSRect statusItemBounds = NSMakeRect(0, - 0, - statusItemWidth, - statusItemHeight); + // Draw background. + BOOL highlight = [self shouldHighlight]; + CGFloat thickness = [[statusItem_ statusBar] thickness]; + NSRect statusItemBounds = NSMakeRect(0, 0, [statusItem_ length], thickness); [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds withHighlight:highlight]; - [statusItem_ setLength:statusItemWidth]; - // Custom ImageView - [image_view_ setFrame: iconRect]; - if (highlight && alternateImage_) { + // Make use of NSImageView to draw the image, which can correctly draw + // template image under dark menu bar. + if (highlight && alternateImage_ && + [image_view_ image] != alternateImage_.get()) { [image_view_ setImage:alternateImage_]; - } else { + } else if ([image_view_ image] != image_.get()) { [image_view_ setImage:image_]; } if (title_) { - NSRect titleDrawRect = NSMakeRect(iconWidth, - 0, - statusItemWidth - kHorizontalMargin, - statusItemHeight); + // Highlight the text when icon is highlighted or in dark mode. + highlight |= [self isDarkMode]; + // Draw title. + NSRect titleDrawRect = NSMakeRect( + [self iconWidth], -kVerticalTitleMargin, [self titleWidth], thickness); [title_ drawInRect:titleDrawRect - withAttributes:[self titleAttributes]]; + withAttributes:[self titleAttributesWithHighlight:highlight]]; } } -- (BOOL) isDarkMode { - return [[[NSAppearance currentAppearance] name] hasPrefix: - NSAppearanceNameVibrantDark]; +- (BOOL)isDarkMode { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSString* mode = [defaults stringForKey:@"AppleInterfaceStyle"]; + return mode && [mode isEqualToString:@"Dark"]; } +// The width of the full status item. +- (CGFloat)fullWidth { + if (title_) + return [self iconWidth] + [self titleWidth] + kHorizontalMargin; + else + return [self iconWidth]; +} + +// The width of the icon. +- (CGFloat)iconWidth { + CGFloat thickness = [[NSStatusBar systemStatusBar] thickness]; + CGFloat imageHeight = [image_ size].height; + CGFloat imageWidth = [image_ size].width; + CGFloat iconWidth = imageWidth; + if (imageWidth < thickness) { + // Image's width must be larger than menu bar's height. + iconWidth = thickness; + } else { + CGFloat verticalMargin = thickness - imageHeight; + // Image must have same horizontal vertical margin. + if (verticalMargin > 0 && imageWidth != imageHeight) + iconWidth = imageWidth + verticalMargin; + CGFloat horizontalMargin = thickness - imageWidth; + // Image must have at least kHorizontalMargin horizontal margin on each + // side. + if (horizontalMargin < 2 * kHorizontalMargin) + iconWidth = imageWidth + 2 * kHorizontalMargin; + } + return iconWidth; +} + +// The width of the title. - (CGFloat)titleWidth { - if (!title_) return 0; - NSAttributedString* attributes = + if (!title_) + return 0; + base::scoped_nsobject attributes( [[NSAttributedString alloc] initWithString:title_ - attributes:[self titleAttributes]]; + attributes:[self titleAttributes]]); return [attributes size].width; } -- (NSDictionary*)titleAttributes { +- (NSDictionary*)titleAttributesWithHighlight:(BOOL)highlight { NSFont* font = [NSFont menuBarFontOfSize:0]; - NSColor* foregroundColor = - [self isDarkMode] ? [NSColor whiteColor] : [NSColor blackColor]; - + NSColor* foregroundColor = highlight ? + [NSColor whiteColor] : + [NSColor colorWithRed:0.265625 green:0.25390625 blue:0.234375 alpha:1.0]; return [NSDictionary dictionaryWithObjectsAndKeys: - font, NSFontAttributeName, - foregroundColor, NSForegroundColorAttributeName, - nil]; + font, NSFontAttributeName, + foregroundColor, NSForegroundColorAttributeName, + nil]; +} + +- (NSDictionary*)titleAttributes { + return [self titleAttributesWithHighlight:[self isDarkMode]]; } - (void)setImage:(NSImage*)image { @@ -144,7 +181,11 @@ const CGFloat kHorizontalMargin = 4; } - (void)setTitle:(NSString*)title { - title_.reset([title copy]); + if (title.length > 0) + title_.reset([title copy]); + else + title_.reset(); + [statusItem_ setLength:[self fullWidth]]; [self setNeedsDisplay:YES]; } @@ -188,7 +229,7 @@ const CGFloat kHorizontalMargin = 4; - (void)popContextMenu { if (menuController_ && ![menuController_ isMenuOpen]) { - // redraw the dray icon to show highlight if it is enabled. + // Redraw the dray icon to show highlight if it is enabled. [self setNeedsDisplay:YES]; [statusItem_ popUpStatusItemMenu:[menuController_ menu]]; // The popUpStatusItemMenu returns only after the showing menu is closed. @@ -222,8 +263,8 @@ const CGFloat kHorizontalMargin = 4; } - (BOOL)shouldHighlight { - BOOL is_menu_open = [menuController_ isMenuOpen]; - return isHighlightEnable_ && (inMouseEventSequence_ || is_menu_open); + BOOL isMenuOpen = menuController_ && [menuController_ isMenuOpen]; + return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen); } - (gfx::Rect)getBoundsFromEvent:(NSEvent*)event { @@ -238,7 +279,6 @@ const CGFloat kHorizontalMargin = 4; namespace atom { TrayIconCocoa::TrayIconCocoa() { - status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]); } TrayIconCocoa::~TrayIconCocoa() { @@ -246,7 +286,13 @@ TrayIconCocoa::~TrayIconCocoa() { } void TrayIconCocoa::SetImage(const gfx::Image& image) { - [status_item_view_ setImage:image.AsNSImage()]; + if (status_item_view_) { + [status_item_view_ setImage:image.AsNSImage()]; + } else { + status_item_view_.reset( + [[StatusItemView alloc] initWithImage:image.AsNSImage() + icon:this]); + } } void TrayIconCocoa::SetPressedImage(const gfx::Image& image) { From 2ab079dc7dea8380e159761a891d3cb1f3f7e2c1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Jul 2015 10:33:38 +0800 Subject: [PATCH 090/172] Bump v0.30.2 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index bf67c767c17f..dc53c6b9575d 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.30.1', + 'version%': '0.30.2', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 28d56286e968..aad2ec56db68 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.30.1 + 0.30.2 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 3485ad963c39..68eff5577f08 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,30,1,0 - PRODUCTVERSION 0,30,1,0 + FILEVERSION 0,30,2,0 + PRODUCTVERSION 0,30,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.30.1" + VALUE "FileVersion", "0.30.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.30.1" + VALUE "ProductVersion", "0.30.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 0240a423bc4f..5612bd6463fc 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 30 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 From e0a117414b9ff6f999a73a07a2ebac0c2be1ce8e Mon Sep 17 00:00:00 2001 From: Jiaji Zhou Date: Thu, 30 Jul 2015 01:21:17 -0700 Subject: [PATCH 091/172] Add missing dependency for ubuntu build I tried to follow the document to build electron on a fresh clean built Ubuntu 15.04. I encountered the following error message when trying to run ./script/bootstrap.py -v Package nss was not found in the pkg-config search path. Perhaps you should add the directory containing `nss.pc' to the PKG_CONFIG_PATH environment variable No package 'nss' found After installing libnss3-dev, the build can pass. --- docs/development/build-instructions-linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/build-instructions-linux.md b/docs/development/build-instructions-linux.md index 3fe3b53c210f..ca0f101e29aa 100644 --- a/docs/development/build-instructions-linux.md +++ b/docs/development/build-instructions-linux.md @@ -17,7 +17,7 @@ On Ubuntu, install the following libraries: $ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \ libnotify-dev libgnome-keyring-dev libgconf2-dev \ libasound2-dev libcap-dev libcups2-dev libxtst-dev \ - libxss1 gcc-multilib g++-multilib + libxss1 libnss3-dev gcc-multilib g++-multilib ``` Other distributions may offer similar packages for installation via package From 239d535cac0ad766f78d5760c55abdde0504d0b9 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 30 Jul 2015 14:42:03 +0530 Subject: [PATCH 092/172] render: executejavascript with option to simulate usergesture --- atom/browser/api/atom_api_web_contents.cc | 5 +++-- atom/browser/api/atom_api_web_contents.h | 3 ++- atom/browser/api/lib/web-contents.coffee | 6 +++--- atom/common/api/api_messages.h | 4 ++++ atom/renderer/atom_render_view_observer.cc | 23 ++++++++++++++++++++++ atom/renderer/atom_render_view_observer.h | 2 ++ docs/api/browser-window.md | 5 +++-- 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 7070b7d6ebab..1f68a4d8ad1d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -572,8 +572,9 @@ void WebContents::InsertCSS(const std::string& css) { web_contents()->InsertCSS(css); } -void WebContents::ExecuteJavaScript(const base::string16& code) { - web_contents()->GetMainFrame()->ExecuteJavaScript(code); +void WebContents::ExecuteJavaScript(const base::string16& code, + bool has_user_gesture) { + Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture)); } void WebContents::OpenDevTools(mate::Arguments* args) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 68e0ad310529..2fbc1d899777 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -65,7 +65,8 @@ class WebContents : public mate::TrackableObject, void SetUserAgent(const std::string& user_agent); std::string GetUserAgent(); void InsertCSS(const std::string& css); - void ExecuteJavaScript(const base::string16& code); + void ExecuteJavaScript(const base::string16& code, + bool has_user_gesture); void OpenDevTools(mate::Arguments* args); void CloseDevTools(); bool IsDevToolsOpened(); diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index cb6cc7c0b3d8..06615e31608f 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -46,11 +46,11 @@ wrapWebContents = (webContents) -> # web contents has been loaded. webContents.loaded = false webContents.once 'did-finish-load', -> @loaded = true - webContents.executeJavaScript = (code) -> + webContents.executeJavaScript = (code, hasUserGesture=false) -> if @loaded - @_executeJavaScript code + @_executeJavaScript code, hasUserGesture else - webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code) + webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture) # The navigation controller. controller = new NavigationController(webContents) diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index eeb26614847b..b32df3cef39d 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -34,6 +34,10 @@ IPC_MESSAGE_ROUTED2(AtomViewMsg_Message, base::string16 /* channel */, base::ListValue /* arguments */) +IPC_MESSAGE_ROUTED2(AtomViewMsg_ExecuteJavaScript, + base::string16 /* code */, + bool /* has user gesture */) + // Sent by the renderer when the draggable regions are updated. IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, std::vector /* regions */) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 02250091a4ab..eb59fe03d3b3 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -26,6 +26,8 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" @@ -113,6 +115,8 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message) IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage) + IPC_MESSAGE_HANDLER(AtomViewMsg_ExecuteJavaScript, + OnJavaScriptExecuteRequest) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -143,4 +147,23 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, } } +void AtomRenderViewObserver::OnJavaScriptExecuteRequest( + const base::string16& code, bool has_user_gesture) { + if (!document_created_) + return; + + if (!render_view()->GetWebView()) + return; + + scoped_ptr gesture( + has_user_gesture ? new blink::WebScopedUserGesture : nullptr); + + v8::Isolate* isolate = blink::mainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + + blink::WebFrame* frame = render_view()->GetWebView()->mainFrame(); + frame->executeScriptAndReturnValue( + blink::WebScriptSource(code)); +} + } // namespace atom diff --git a/atom/renderer/atom_render_view_observer.h b/atom/renderer/atom_render_view_observer.h index 4b9d59f3fa08..85a8c159d97e 100644 --- a/atom/renderer/atom_render_view_observer.h +++ b/atom/renderer/atom_render_view_observer.h @@ -32,6 +32,8 @@ class AtomRenderViewObserver : public content::RenderViewObserver { void OnBrowserMessage(const base::string16& channel, const base::ListValue& args); + void OnJavaScriptExecuteRequest(const base::string16& code, + bool has_user_gesture); // Weak reference to renderer client. AtomRendererClient* renderer_client_; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7257158ec1a5..a5f7ab2880fe 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -905,11 +905,12 @@ Returns a `String` represents the user agent for this page. Injects CSS into this page. -### WebContents.executeJavaScript(code) +### WebContents.executeJavaScript(code, userGesture) * `code` String +* `userGesture` Boolean - Default false -Evaluates `code` in page. +Evaluates `code` in page. If `userGesture` is set will simulate user gesture. ### WebContents.setAudioMuted(muted) From 92ea533aee5fd2f16334796e8d8738e2b3568756 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 29 Jul 2015 16:50:50 +0530 Subject: [PATCH 093/172] webFrame: api to make scheme bypass CSP --- atom/renderer/api/atom_api_web_frame.cc | 42 ++++++++++--------------- atom/renderer/api/atom_api_web_frame.h | 3 ++ docs/api/web-frame.md | 9 +++++- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 7b1666e680c3..783650516bfa 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -4,12 +4,6 @@ #include "atom/renderer/api/atom_api_web_frame.h" -// This defines are required by SchemeRegistry.h. -#define ALWAYS_INLINE inline -#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE) // NOLINT -#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE) // NOLINT -#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE) // NOLINT - #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" @@ -19,29 +13,11 @@ #include "native_mate/object_template_builder.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/WebKit/public/web/WebView.h" -#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h" #include "atom/common/node_includes.h" -namespace mate { - -template<> -struct Converter { - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - WTF::String* out) { - if (!val->IsString()) - return false; - - v8::String::Value s(val); - *out = WTF::String(reinterpret_cast(*s), s.length()); - return true; - } -}; - -} // namespace mate - namespace atom { namespace api { @@ -106,6 +82,18 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args, web_frame_->view()->setSpellCheckClient(spell_check_client_.get()); } +void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { + // Register scheme to secure list (https, wss, data). + blink::WebSecurityPolicy::registerURLSchemeAsSecure( + blink::WebString::fromUTF8(scheme)); +} + +void WebFrame::RegisterURLSchemeAsBypassingCsp(const std::string& scheme) { + // Register scheme to bypass pages's Content Security Policy. + blink::WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy( + blink::WebString::fromUTF8(scheme)); +} + mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( v8::Isolate* isolate) { return mate::ObjectTemplateBuilder(isolate) @@ -121,7 +109,9 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( .SetMethod("attachGuest", &WebFrame::AttachGuest) .SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider) .SetMethod("registerUrlSchemeAsSecure", - &blink::SchemeRegistry::registerURLSchemeAsSecure); + &WebFrame::RegisterURLSchemeAsSecure) + .SetMethod("registerUrlSchemeAsBypassingCsp", + &WebFrame::RegisterURLSchemeAsBypassingCsp); } // static diff --git a/atom/renderer/api/atom_api_web_frame.h b/atom/renderer/api/atom_api_web_frame.h index e57efd45cfb8..26b8178e98ab 100644 --- a/atom/renderer/api/atom_api_web_frame.h +++ b/atom/renderer/api/atom_api_web_frame.h @@ -54,6 +54,9 @@ class WebFrame : public mate::Wrappable { bool auto_spell_correct_turned_on, v8::Local provider); + void RegisterURLSchemeAsSecure(const std::string& scheme); + void RegisterURLSchemeAsBypassingCsp(const std::string& scheme); + // mate::Wrappable: virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate); diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index 73b9ee50577f..e0b04bfe3f08 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -57,10 +57,17 @@ require('web-frame').setSpellCheckProvider("en-US", true, { * `scheme` String -Sets the `scheme` as secure scheme. +Registers the `scheme` as secure scheme. Secure schemes do not trigger mixed content warnings. For example, `https` and `data` are secure schemes because they cannot be corrupted by active network attackers. +## webFrame.registerUrlSchemeAsBypassingCsp(scheme) + +* `scheme` String + +Resources will be loaded from this `scheme` regardless of +page's Content Security Policy. + [spellchecker]: https://github.com/atom/node-spellchecker From c69002b0dd517e3c0e9698851a3ac457337c67e4 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 31 Jul 2015 09:57:08 +0800 Subject: [PATCH 094/172] Fix: browser window will be resiable when calling `window.setResizable(false)` twice. --- atom/browser/native_window_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index d5f12bde13dd..295c0ac5400a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -589,7 +589,7 @@ void NativeWindowMac::SetResizable(bool resizable) { [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; } else { [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; - [window_ setStyleMask:[window_ styleMask] ^ NSResizableWindowMask]; + [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; } } From ddf2cfd48df38fb40ad56b38c7da887cbd508b3a Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:26:57 +0900 Subject: [PATCH 095/172] Support remote Promise in renderer --- atom/browser/lib/rpc-server.coffee | 3 +++ atom/renderer/api/lib/remote.coffee | 1 + 2 files changed, 4 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index ab86a0c45518..d1e3267784e5 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -10,6 +10,7 @@ valueToMeta = (sender, value) -> meta.type = 'buffer' if Buffer.isBuffer value meta.type = 'value' if value is null meta.type = 'array' if Array.isArray value + meta.type = 'promise' if Promise.resolve(value) == value # Treat the arguments object as array. meta.type = 'array' if meta.type is 'object' and value.callee? and value.length? @@ -29,6 +30,8 @@ valueToMeta = (sender, value) -> meta.members.push {name: prop, type: typeof field} for prop, field of value else if meta.type is 'buffer' meta.value = Array::slice.call value, 0 + else if meta.type is 'promise' + meta.then = valueToMeta(sender, value.then.bind(value)) else meta.type = 'value' meta.value = value diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index b159125b7949..5ad7c80ca01f 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -44,6 +44,7 @@ metaToValue = (meta) -> when 'value' then meta.value when 'array' then (metaToValue(el) for el in meta.members) when 'buffer' then new Buffer(meta.value) + when 'promise' then Promise.resolve(then: metaToValue(meta.then)) when 'error' throw new Error("#{meta.message}\n#{meta.stack}") else From c7d1f4f6b2dc028869ba46fbe6c81a01906b3be6 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:32:07 +0900 Subject: [PATCH 096/172] Add spec for remote Promise --- spec/api-ipc-spec.coffee | 9 +++++++++ spec/fixtures/module/promise.js | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 spec/fixtures/module/promise.js diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index d7f77b14ce2e..04da0026e6bd 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -52,6 +52,15 @@ describe 'ipc module', -> print_name = remote.require path.join(fixtures, 'module', 'print_name.js') assert.equal print_name.print(buf), 'Buffer' + describe 'remote promise in renderer', -> + it 'can be used as promise', (done) -> + promise = remote.require path.join(fixtures, 'module', 'promise.js') + promise.toPromise(1234) + .then (value) => value * 2 + .then (value) => + assert.equal value, 2468 + done() + describe 'ipc.sender.send', -> it 'should work when sending an object containing id property', (done) -> obj = id: 1, name: 'ly' diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js new file mode 100644 index 000000000000..a82acc4b11a5 --- /dev/null +++ b/spec/fixtures/module/promise.js @@ -0,0 +1,3 @@ +exports.toPromise = function (value) { + return Promise.resolve(value); +}; From 92af275f98dfbbd936ab29d1d810705dfc02baf9 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:45:22 +0900 Subject: [PATCH 097/172] Support remote Promise in browser --- atom/browser/lib/rpc-server.coffee | 1 + atom/renderer/api/lib/remote.coffee | 2 ++ 2 files changed, 3 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index d1e3267784e5..8c9671816631 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -50,6 +50,7 @@ unwrapArgs = (sender, args) -> when 'remote-object' then objectsRegistry.get meta.id when 'array' then unwrapArgs sender, meta.value when 'buffer' then new Buffer(meta.value) + when 'promise' then Promise.resolve(then: metaToValue(meta.then)) when 'object' ret = v8Util.createObjectWithName meta.name for member in meta.members diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 5ad7c80ca01f..7370440c6c2d 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -20,6 +20,8 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) + else if Promise.resolve(value) == value + type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId' else if value? and typeof value is 'object' From 428ad20807f867f1c8e14237111f6edca542df83 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:45:53 +0900 Subject: [PATCH 098/172] Change spec to test Promise in both side --- spec/api-ipc-spec.coffee | 7 +++---- spec/fixtures/module/promise.js | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 04da0026e6bd..7c6148b559b0 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -52,11 +52,10 @@ describe 'ipc module', -> print_name = remote.require path.join(fixtures, 'module', 'print_name.js') assert.equal print_name.print(buf), 'Buffer' - describe 'remote promise in renderer', -> - it 'can be used as promise', (done) -> + describe 'remote promise', -> + it 'can be used as promise in each side', (done) -> promise = remote.require path.join(fixtures, 'module', 'promise.js') - promise.toPromise(1234) - .then (value) => value * 2 + promise.twicePromise(Promise.resolve(1234)) .then (value) => assert.equal value, 2468 done() diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js index a82acc4b11a5..2e52ed374400 100644 --- a/spec/fixtures/module/promise.js +++ b/spec/fixtures/module/promise.js @@ -1,3 +1,5 @@ -exports.toPromise = function (value) { - return Promise.resolve(value); -}; +exports.twicePromise = function (promise) { + return promise.then(function (value) { + return value * 2; + }); +} From 9fb03d584c4f2ebcc726c652748eb5661f36f4b3 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 30 Jul 2015 21:56:57 +0530 Subject: [PATCH 099/172] add spec and fix docs --- docs/api/browser-window.md | 4 +++- docs/api/web-view-tag.md | 7 +++++-- spec/fixtures/pages/fullscreen.html | 1 + spec/webview-spec.coffee | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/pages/fullscreen.html diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index a5f7ab2880fe..e4cabd52b3b4 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -910,7 +910,9 @@ Injects CSS into this page. * `code` String * `userGesture` Boolean - Default false -Evaluates `code` in page. If `userGesture` is set will simulate user gesture. +Evaluates `code` in page. If `userGesture` is set will create user gesture context, +HTML api like `requestFullScreen` which require user action can take advantage +of this option for automation. ### WebContents.setAudioMuted(muted) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 0ff54c161704..a74f5fb50c77 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -225,11 +225,14 @@ Returns a `String` represents the user agent for guest page. Injects CSS into guest page. -### ``.executeJavaScript(code) +### ``.executeJavaScript(code, userGesture) * `code` String +* `userGesture` Boolean - Default false -Evaluates `code` in guest page. +Evaluates `code` in page. If `userGesture` is set will create user gesture context, +HTML api like `requestFullScreen` which require user action can take advantage +of this option for automation. ### ``.openDevTools() diff --git a/spec/fixtures/pages/fullscreen.html b/spec/fixtures/pages/fullscreen.html new file mode 100644 index 000000000000..4e5648e0194d --- /dev/null +++ b/spec/fixtures/pages/fullscreen.html @@ -0,0 +1 @@ + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 7ab8969e7719..ef0763b0147c 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -261,3 +261,17 @@ describe ' tag', -> done() webview.src = "file://#{fixtures}/pages/dom-ready.html?port=#{port}" document.body.appendChild webview + + describe 'executeJavaScript', -> + it 'should support user gesture', (done) -> + listener = (e) -> + webview.removeEventListener 'enter-html-full-screen', listener + done() + listener2 = (e) -> + jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()' + webview.executeJavaScript jsScript, true + webview.removeEventListener 'did-finish-load', listener2 + webview.addEventListener 'enter-html-full-screen', listener + webview.addEventListener 'did-finish-load', listener2 + webview.src = "file://#{fixtures}/pages/fullscreen.html" + document.body.appendChild webview From 9dab6e02ca5e713a0a10b6af9960578cad360653 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 31 Jul 2015 20:14:50 +0200 Subject: [PATCH 100/172] Fix typo --- atom/browser/native_window_views.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index dbd8bf26ce3d..62cf51f4d84e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -184,7 +184,7 @@ const char* AppCommandToString(int command_id) { case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE: return "dictate-or-command-control-toggle"; default: - return "unkown"; + return "unknown"; } } #endif From c0ce8723d49d7ae0923b352aca95e32a9f4e0df3 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 31 Jul 2015 20:16:26 +0200 Subject: [PATCH 101/172] Fix typo --- atom/renderer/lib/web-view/guest-view-internal.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index cc0a7c928e38..b62418d146d9 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -27,7 +27,7 @@ WEB_VIEW_EVENTS = 'leave-html-full-screen': [] dispatchEvent = (webView, event, args...) -> - throw new Error("Unkown event #{event}") unless WEB_VIEW_EVENTS[event]? + throw new Error("Unknown event #{event}") unless WEB_VIEW_EVENTS[event]? domEvent = new Event(event) for f, i in WEB_VIEW_EVENTS[event] domEvent[f] = args[i] From c8a794ac3474a034fd32ab74071222a87948be32 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Sat, 1 Aug 2015 12:20:16 +0900 Subject: [PATCH 102/172] Use constructor name to check if Promise --- atom/browser/lib/rpc-server.coffee | 2 +- atom/renderer/api/lib/remote.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 8c9671816631..3eba472570a7 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -10,7 +10,7 @@ valueToMeta = (sender, value) -> meta.type = 'buffer' if Buffer.isBuffer value meta.type = 'value' if value is null meta.type = 'array' if Array.isArray value - meta.type = 'promise' if Promise.resolve(value) == value + meta.type = 'promise' if value? and value.constructor.name is 'Promise' # Treat the arguments object as array. meta.type = 'array' if meta.type is 'object' and value.callee? and value.length? diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 7370440c6c2d..29a24b1789ef 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -20,7 +20,7 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) - else if Promise.resolve(value) == value + else if value? and value.constructor.name is 'Promise' type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId' From e135bcb5b71697c4be49620e89cd07da63a47925 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 3 Aug 2015 14:43:01 +0800 Subject: [PATCH 103/172] docs: userGesture is optional --- docs/api/browser-window.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e4cabd52b3b4..add5cfff8ba9 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -905,14 +905,16 @@ Returns a `String` represents the user agent for this page. Injects CSS into this page. -### WebContents.executeJavaScript(code, userGesture) +### WebContents.executeJavaScript(code[, userGesture]) * `code` String -* `userGesture` Boolean - Default false +* `userGesture` Boolean -Evaluates `code` in page. If `userGesture` is set will create user gesture context, -HTML api like `requestFullScreen` which require user action can take advantage -of this option for automation. +Evaluates `code` in page. + +In browser some HTML APIs like `requestFullScreen` can only be invoked if it +is started by user gesture, by specifying `userGesture` to `true` developers +can ignore this limitation. ### WebContents.setAudioMuted(muted) From 9e922dd0c7d0e8f0bd817e6c6879fd0e360b60de Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 15:40:31 +0800 Subject: [PATCH 104/172] spec: Don't set window to fullscreen unless under travis --- spec/webview-spec.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index ef0763b0147c..ba3478fca557 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -263,6 +263,8 @@ describe ' tag', -> document.body.appendChild webview describe 'executeJavaScript', -> + return unless process.env.TRAVIS is 'true' + it 'should support user gesture', (done) -> listener = (e) -> webview.removeEventListener 'enter-html-full-screen', listener From 039d4aaecb56568a73c50217e766c3505c46d0de Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 15:46:59 +0800 Subject: [PATCH 105/172] spec: Test window.opener --- spec/chromium-spec.coffee | 25 ++++++++++++++++++++++++- spec/fixtures/pages/window-opener.html | 8 ++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/pages/window-opener.html diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index 8ca7e9800fe5..375f98966bea 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -3,6 +3,7 @@ http = require 'http' https = require 'https' path = require 'path' ws = require 'ws' +remote = require 'remote' describe 'chromium feature', -> fixtures = path.resolve __dirname, 'fixtures' @@ -39,9 +40,31 @@ describe 'chromium feature', -> assert.equal b.constructor.name, 'BrowserWindowProxy' b.close() + describe 'window.opener', -> + ipc = remote.require 'ipc' + url = "file://#{fixtures}/pages/window-opener.html" + w = null + + afterEach -> + w?.destroy() + ipc.removeAllListeners 'opener' + + it 'is null for main window', (done) -> + ipc.on 'opener', (event, opener) -> + done(if opener is null then undefined else opener) + BrowserWindow = remote.require 'browser-window' + w = new BrowserWindow(show: false) + w.loadUrl url + + it 'is not null for window opened by window.open', (done) -> + b = window.open url, 'test2', 'show=no' + ipc.on 'opener', (event, opener) -> + b.close() + done(if opener isnt null then undefined else opener) + describe 'creating a Uint8Array under browser side', -> it 'does not crash', -> - RUint8Array = require('remote').getGlobal 'Uint8Array' + RUint8Array = remote.getGlobal 'Uint8Array' new RUint8Array describe 'webgl', -> diff --git a/spec/fixtures/pages/window-opener.html b/spec/fixtures/pages/window-opener.html new file mode 100644 index 000000000000..0b5ecd556c9b --- /dev/null +++ b/spec/fixtures/pages/window-opener.html @@ -0,0 +1,8 @@ + + + + + + From 2a305207990e5d09a1b541006108ecdb0fa5e27a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 15:47:12 +0800 Subject: [PATCH 106/172] Only set window.opener for windows opened by window.open --- atom/browser/lib/guest-window-manager.coffee | 3 +++ atom/renderer/lib/override.coffee | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index 6f5040ce21d3..f92c1a46c051 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -64,3 +64,6 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, mess ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) -> BrowserWindow.fromId(guestId)?.webContents?[method] args... + +ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_IS_GUEST_WINDOW', (event) -> + event.returnValue = v8Util.getHiddenValue(event.sender, 'embedder') isnt undefined diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index aea7feb3cbfe..d0f1fabc4ac9 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -91,7 +91,7 @@ window.prompt = -> throw new Error('prompt() is and will not be supported.') # Simple implementation of postMessage. -unless process.guestInstanceId? +if ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_IS_GUEST_WINDOW' window.opener = postMessage: (message, targetOrigin='*') -> ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin From 69b20d25ee0277a2c55d4be46842274e84940b23 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 16:48:10 +0800 Subject: [PATCH 107/172] Update brightray for #2294 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 956ee8a3296f..328fde765587 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 956ee8a3296f2ea8eaf48b6d6c9bbb7ba26d4c1a +Subproject commit 328fde7655872f48285582af82a40e60118493f1 From 1347c61c8ebaa02a947e303dcab89ed675228673 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 17:13:05 +0800 Subject: [PATCH 108/172] Set AppUserModelID for all renderer processes --- atom/browser/atom_browser_client.cc | 14 ++++++++++++++ atom/browser/native_window.cc | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index f98f2b2a8873..65fd7cd031dd 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -4,6 +4,10 @@ #include "atom/browser/atom_browser_client.h" +#if defined(OS_WIN) +#include +#endif + #include "atom/browser/atom_access_token_store.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" @@ -190,10 +194,20 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( if (process_type != "renderer") return; + // The registered standard schemes. if (!g_custom_schemes.empty()) command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes, g_custom_schemes); +#if defined(OS_WIN) + // Append --app-user-model-id. + PWSTR current_app_id; + if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) { + command_line->AppendSwitchNative(switches::kAppUserModelId, current_app_id); + CoTaskMemFree(current_app_id); + } +#endif + NativeWindow* window; WebViewManager::WebViewInfo info; ProcessOwner owner = GetProcessOwner(process_id, &window, &info); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index fb9bab766dd8..d3c40f928272 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -8,10 +8,6 @@ #include #include -#if defined(OS_WIN) -#include -#endif - #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/window_list.h" @@ -384,15 +380,6 @@ void NativeWindow::AppendExtraCommandLineSwitches( command_line->AppendSwitchASCII(switches::kZoomFactor, base::DoubleToString(zoom_factor_)); -#if defined(OS_WIN) - // Append --app-user-model-id. - PWSTR current_app_id; - if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) { - command_line->AppendSwitchNative(switches::kAppUserModelId, current_app_id); - CoTaskMemFree(current_app_id); - } -#endif - if (web_preferences_.IsEmpty()) return; From 14803e4cf88467a3fe5cad29bc8308e3fe574404 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 19:18:12 +0800 Subject: [PATCH 109/172] Close handle when waiting is end --- atom/common/crash_reporter/crash_reporter_win.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/atom/common/crash_reporter/crash_reporter_win.cc b/atom/common/crash_reporter/crash_reporter_win.cc index a348cf012612..5c4f9fb4f24f 100644 --- a/atom/common/crash_reporter/crash_reporter_win.cc +++ b/atom/common/crash_reporter/crash_reporter_win.cc @@ -51,8 +51,10 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name, // Wait until the crash service is started. HANDLE waiting_event = ::CreateEventW(NULL, TRUE, FALSE, L"g_atom_shell_crash_service"); - if (waiting_event != INVALID_HANDLE_VALUE) + if (waiting_event != NULL) { WaitForSingleObject(waiting_event, 1000); + CloseHandle(waiting_event); + } // ExceptionHandler() attaches our handler and ~ExceptionHandler() detaches // it, so we must explicitly reset *before* we instantiate our new handler From db58048077f604f46814a7e5dff3d87a1fd7e3f3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 19:30:35 +0800 Subject: [PATCH 110/172] Use different name for wait events for different apps --- atom/common/crash_reporter/crash_reporter_win.cc | 12 +++++++----- atom/common/crash_reporter/win/crash_service.cc | 14 ++++++++------ atom/common/crash_reporter/win/crash_service.h | 3 ++- .../crash_reporter/win/crash_service_main.cc | 3 ++- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/atom/common/crash_reporter/crash_reporter_win.cc b/atom/common/crash_reporter/crash_reporter_win.cc index 5c4f9fb4f24f..be096da80e2c 100644 --- a/atom/common/crash_reporter/crash_reporter_win.cc +++ b/atom/common/crash_reporter/crash_reporter_win.cc @@ -21,6 +21,7 @@ const MINIDUMP_TYPE kSmallDumpType = static_cast( MiniDumpWithProcessThreadData | // Get PEB and TEB. MiniDumpWithUnloadedModules); // Get unloaded modules when available. +const wchar_t kWaitEventFormat[] = L"$1CrashServiceWaitEvent"; const wchar_t kPipeNameFormat[] = L"\\\\.\\pipe\\$1 Crash Service"; } // namespace @@ -47,13 +48,14 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name, base::string16 pipe_name = ReplaceStringPlaceholders( kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL); + base::string16 wait_name = ReplaceStringPlaceholders( + kWaitEventFormat, base::UTF8ToUTF16(product_name), NULL); // Wait until the crash service is started. - HANDLE waiting_event = - ::CreateEventW(NULL, TRUE, FALSE, L"g_atom_shell_crash_service"); - if (waiting_event != NULL) { - WaitForSingleObject(waiting_event, 1000); - CloseHandle(waiting_event); + HANDLE wait_event = ::CreateEventW(NULL, TRUE, FALSE, wait_name.c_str()); + if (wait_event != NULL) { + WaitForSingleObject(wait_event, 1000); + CloseHandle(wait_event); } // ExceptionHandler() attaches our handler and ~ExceptionHandler() detaches diff --git a/atom/common/crash_reporter/win/crash_service.cc b/atom/common/crash_reporter/win/crash_service.cc index 10e0fdfcc555..611c39219bfd 100644 --- a/atom/common/crash_reporter/win/crash_service.cc +++ b/atom/common/crash_reporter/win/crash_service.cc @@ -14,6 +14,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/time/time.h" #include "base/win/windows_version.h" #include "vendor/breakpad/src/client/windows/crash_generation/client_info.h" @@ -24,6 +25,7 @@ namespace breakpad { namespace { +const wchar_t kWaitEventFormat[] = L"$1CrashServiceWaitEvent"; const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; const wchar_t kGoogleReportURL[] = L"https://clients2.google.com/cr/report"; @@ -193,7 +195,8 @@ CrashService::~CrashService() { delete sender_; } -bool CrashService::Initialize(const base::FilePath& operating_dir, +bool CrashService::Initialize(const base::string16& application_name, + const base::FilePath& operating_dir, const base::FilePath& dumps_path) { using google_breakpad::CrashReportSender; using google_breakpad::CrashGenerationServer; @@ -298,11 +301,10 @@ bool CrashService::Initialize(const base::FilePath& operating_dir, // Create or open an event to signal the browser process that the crash // service is initialized. - HANDLE running_event = - ::CreateEventW(NULL, TRUE, TRUE, L"g_atom_shell_crash_service"); - // If the browser already had the event open, the CreateEvent call did not - // signal it. We need to do it manually. - ::SetEvent(running_event); + base::string16 wait_name = ReplaceStringPlaceholders( + kWaitEventFormat, application_name, NULL); + HANDLE wait_event = ::CreateEventW(NULL, TRUE, FALSE, wait_name.c_str()); + ::SetEvent(wait_event); return true; } diff --git a/atom/common/crash_reporter/win/crash_service.h b/atom/common/crash_reporter/win/crash_service.h index 730e4da3c6b2..7195ec2a958c 100644 --- a/atom/common/crash_reporter/win/crash_service.h +++ b/atom/common/crash_reporter/win/crash_service.h @@ -37,7 +37,8 @@ class CrashService { // other members in that case. |operating_dir| is where the CrashService // should store breakpad's checkpoint file. |dumps_path| is the directory // where the crash dumps should be stored. - bool Initialize(const base::FilePath& operating_dir, + bool Initialize(const base::string16& application_name, + const base::FilePath& operating_dir, const base::FilePath& dumps_path); // Command line switches: diff --git a/atom/common/crash_reporter/win/crash_service_main.cc b/atom/common/crash_reporter/win/crash_service_main.cc index 0bd72deba9e9..7a5eeb10133a 100644 --- a/atom/common/crash_reporter/win/crash_service_main.cc +++ b/atom/common/crash_reporter/win/crash_service_main.cc @@ -77,7 +77,8 @@ int Main(const wchar_t* cmd) { cmd_line.AppendSwitchNative("pipe-name", pipe_name); breakpad::CrashService crash_service; - if (!crash_service.Initialize(operating_dir, operating_dir)) + if (!crash_service.Initialize(application_name, operating_dir, + operating_dir)) return 2; VLOG(1) << "Ready to process crash requests"; From c872b1a770c49df662fded29005ab760ed2dfe0c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 19:35:46 +0800 Subject: [PATCH 111/172] Use different name for window class name --- atom/common/crash_reporter/win/crash_service.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/atom/common/crash_reporter/win/crash_service.cc b/atom/common/crash_reporter/win/crash_service.cc index 611c39219bfd..d315b0b9419e 100644 --- a/atom/common/crash_reporter/win/crash_service.cc +++ b/atom/common/crash_reporter/win/crash_service.cc @@ -26,6 +26,8 @@ namespace breakpad { namespace { const wchar_t kWaitEventFormat[] = L"$1CrashServiceWaitEvent"; +const wchar_t kClassNameFormat[] = L"$1CrashServiceWindow"; + const wchar_t kTestPipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; const wchar_t kGoogleReportURL[] = L"https://clients2.google.com/cr/report"; @@ -113,13 +115,18 @@ LRESULT __stdcall CrashSvcWndProc(HWND hwnd, UINT message, // This is the main and only application window. HWND g_top_window = NULL; -bool CreateTopWindow(HINSTANCE instance, bool visible) { +bool CreateTopWindow(HINSTANCE instance, + const base::string16& application_name, + bool visible) { + base::string16 class_name = ReplaceStringPlaceholders( + kClassNameFormat, application_name, NULL); + WNDCLASSEXW wcx = {0}; wcx.cbSize = sizeof(wcx); wcx.style = CS_HREDRAW | CS_VREDRAW; wcx.lpfnWndProc = CrashSvcWndProc; wcx.hInstance = instance; - wcx.lpszClassName = L"crash_svc_class"; + wcx.lpszClassName = class_name.c_str(); ATOM atom = ::RegisterClassExW(&wcx); DWORD style = visible ? WS_POPUPWINDOW | WS_VISIBLE : WS_OVERLAPPED; @@ -263,6 +270,7 @@ bool CrashService::Initialize(const base::string16& application_name, } if (!CreateTopWindow(::GetModuleHandleW(NULL), + application_name, !cmd_line.HasSwitch(kNoWindow))) { LOG(ERROR) << "could not create window"; if (security_attributes.lpSecurityDescriptor) From 613e5c77ea8386f37b8c6c3a89cbac7ed66936aa Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 4 Aug 2015 19:45:44 +0800 Subject: [PATCH 112/172] Check context menu when calling popContextMenu API. --- atom/browser/ui/win/notify_icon.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index fd9a90ae1d5d..962dc871b5b6 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -162,6 +162,9 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, } void NotifyIcon::PopContextMenu(const gfx::Point& pos) { + // Returns if context menu isn't set. + if (!menu_model_) + return; // Set our window as the foreground window, so the context menu closes when // we click away from it. if (!SetForegroundWindow(window_)) From 7910fe7785dafcb6b16780c5414bca382dc0efd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Tue, 4 Aug 2015 08:27:17 -0400 Subject: [PATCH 113/172] Only build pushes on Travis for master branch [ci skip] --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index ff7272e3e576..4d4cd5dde9f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,3 +22,7 @@ matrix: - env: TARGET_ARCH=ia32 script: './script/cibuild' + +branches: + only: + - master From 50f226e34e3a8c27628b62890f9075eb137312c2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 21:56:17 +0800 Subject: [PATCH 114/172] win: Use app name as default title of message box TaskDialogIndirect doesn't allow empty name, if we set empty title it will show "electron.exe" in title. --- atom/browser/ui/message_box_win.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index 58d1badc3bfd..051f8f5eff6c 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -10,6 +10,7 @@ #include #include +#include "atom/browser/browser.h" #include "atom/browser/native_window_views.h" #include "base/callback.h" #include "base/strings/string_util.h" @@ -87,7 +88,12 @@ int ShowMessageBoxUTF16(HWND parent, config.hInstance = GetModuleHandle(NULL); config.dwFlags = flags; - if (!title.empty()) + // TaskDialogIndirect doesn't allow empty name, if we set empty title it + // will show "electron.exe" in title. + base::string16 app_name = base::UTF8ToUTF16(Browser::Get()->GetName()); + if (title.empty()) + config.pszWindowTitle = app_name.c_str(); + else config.pszWindowTitle = title.c_str(); base::win::ScopedHICON hicon; From 6b65a6611996523f9f26d1e6e408a7cddf7d1b35 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 4 Aug 2015 22:52:44 +0800 Subject: [PATCH 115/172] Update brightray for #2263 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 328fde765587..f4470ee48a74 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 328fde7655872f48285582af82a40e60118493f1 +Subproject commit f4470ee48a748888bccba21845bfd65caaa1a6ce From 3b05b135a513d658f216009faab3e9b6745cdd5c Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 5 Aug 2015 01:42:57 +0530 Subject: [PATCH 116/172] tracing: fix api and docs --- atom/browser/api/atom_api_content_tracing.cc | 32 +++++++++++++++++--- atom/browser/api/lib/content-tracing.coffee | 6 ---- docs/api/content-tracing.md | 30 +++++++++++++----- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index 6da450185cd7..9507d19d399a 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -7,6 +7,7 @@ #include "atom/common/native_mate_converters/file_path_converter.h" #include "base/bind.h" +#include "base/files/file_util.h" #include "content/public/browser/tracing_controller.h" #include "native_mate/callback.h" #include "native_mate/dictionary.h" @@ -46,6 +47,31 @@ struct Converter { namespace { +using CompletionCallback = base::Callback; + +scoped_refptr GetTraceDataSink( + const base::FilePath& path, const CompletionCallback& callback) { + base::FilePath result_file_path = path; + if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path)) + LOG(ERROR) << "Creating temporary file failed"; + + return TracingController::CreateFileSink(result_file_path, + base::Bind(callback, + result_file_path)); +} + +void StopRecording(const base::FilePath& path, + const CompletionCallback& callback) { + TracingController::GetInstance()->DisableRecording( + GetTraceDataSink(path, callback)); +} + +void CaptureMonitoringSnapshot(const base::FilePath& path, + const CompletionCallback& callback) { + TracingController::GetInstance()->CaptureMonitoringSnapshot( + GetTraceDataSink(path, callback)); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { auto controller = base::Unretained(TracingController::GetInstance()); @@ -54,14 +80,12 @@ void Initialize(v8::Local exports, v8::Local unused, &TracingController::GetCategories, controller)); dict.SetMethod("startRecording", base::Bind( &TracingController::EnableRecording, controller)); - dict.SetMethod("stopRecording", base::Bind( - &TracingController::DisableRecording, controller, nullptr)); + dict.SetMethod("stopRecording", &StopRecording); dict.SetMethod("startMonitoring", base::Bind( &TracingController::EnableMonitoring, controller)); dict.SetMethod("stopMonitoring", base::Bind( &TracingController::DisableMonitoring, controller)); - dict.SetMethod("captureMonitoringSnapshot", base::Bind( - &TracingController::CaptureMonitoringSnapshot, controller, nullptr)); + dict.SetMethod("captureMonitoringSnapshot", &CaptureMonitoringSnapshot); dict.SetMethod("getTraceBufferUsage", base::Bind( &TracingController::GetTraceBufferUsage, controller)); dict.SetMethod("setWatchEvent", base::Bind( diff --git a/atom/browser/api/lib/content-tracing.coffee b/atom/browser/api/lib/content-tracing.coffee index 774661a1b867..08cd36e4aa59 100644 --- a/atom/browser/api/lib/content-tracing.coffee +++ b/atom/browser/api/lib/content-tracing.coffee @@ -1,7 +1 @@ module.exports = process.atomBinding 'content_tracing' - -# Mirrored from content::TracingController::Options -module.exports.DEFAULT_OPTIONS = 0 -module.exports.ENABLE_SYSTRACE = 1 << 0 -module.exports.ENABLE_SAMPLING = 1 << 1 -module.exports.RECORD_CONTINUOUSLY = 1 << 2 diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index c7575ba8a23f..eab7b15d7129 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -28,10 +28,10 @@ are reached. Once all child processes have acked to the `getCategories` request, `callback` is invoked with an array of category groups. -## tracing.startRecording(categoryFilter, options, callback) +## tracing.startRecording(categoryFilter, traceOptions, callback) * `categoryFilter` String -* `options` Integer +* `traceOptions` String * `callback` Function Start recording on all processes. @@ -51,9 +51,23 @@ Examples: * `test_MyTest*,test_OtherStuff`, * `"-excluded_category1,-excluded_category2` -`options` controls what kind of tracing is enabled, it could be a OR-ed -combination of `tracing.DEFAULT_OPTIONS`, `tracing.ENABLE_SYSTRACE`, -`tracing.ENABLE_SAMPLING` and `tracing.RECORD_CONTINUOUSLY`. +`traceOptions` controls what kind of tracing is enabled, it is a comma-delimited list. +Possible options are: + +* `record-until-full` +* `record-continuously` +* `trace-to-console` +* `enable-sampling` +* `enable-systrace` + +The first 3 options are trace recoding modes and hence mutually exclusive. +If more than one trace recording modes appear in the `traceOptions` string, +the last one takes precedence. If none of the trace recording mode is specified, +recording mode is `record-until-full`. + +The trace option will first be reset to the default option (record_mode set to +`record-until-full`, enable_sampling and enable_systrace set to false) +before options parsed from `traceOptions` are applied on it. ## tracing.stopRecording(resultFilePath, callback) @@ -75,10 +89,10 @@ Trace data will be written into `resultFilePath` if it is not empty, or into a temporary file. The actual file path will be passed to `callback` if it's not null. -## tracing.startMonitoring(categoryFilter, options, callback) +## tracing.startMonitoring(categoryFilter, traceOptions, callback) * `categoryFilter` String -* `options` Integer +* `traceOptions` String * `callback` Function Start monitoring on all processes. @@ -107,7 +121,7 @@ Get the current monitoring traced data. Child processes typically are caching trace data and only rarely flush and send trace data back to the main process. That is because it may be an expensive -operation to send the trace data over IPC, and we would like to avoid unneeded +operation to send the trace data over IPC, and we would like to avoid unneeded runtime overhead of tracing. So, to end tracing, we must asynchronously ask all child processes to flush any pending trace data. From 58c04862365b421000f042b12e33047537f9c110 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 12:32:22 +0800 Subject: [PATCH 117/172] Remove duplicate UpdateDraggableRegions --- atom/browser/native_window.cc | 28 ++++++++++++++++++++++ atom/browser/native_window.h | 15 ++++++++---- atom/browser/native_window_mac.h | 9 -------- atom/browser/native_window_mac.mm | 36 ++--------------------------- atom/browser/native_window_views.cc | 27 ++-------------------- atom/browser/native_window_views.h | 7 ------ 6 files changed, 43 insertions(+), 79 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index d3c40f928272..c9d68df640a5 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -68,6 +68,25 @@ const char* kWebRuntimeFeatures[] = { switches::kPageVisibility, }; +// Convert draggable regions in raw format to SkRegion format. Caller is +// responsible for deleting the returned SkRegion instance. +SkRegion* DraggableRegionsToSkRegion( + const std::vector& regions) { + SkRegion* sk_region = new SkRegion; + for (std::vector::const_iterator iter = regions.begin(); + iter != regions.end(); + ++iter) { + const DraggableRegion& region = *iter; + sk_region->op( + region.bounds.x(), + region.bounds.y(), + region.bounds.right(), + region.bounds.bottom(), + region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); + } + return sk_region; +} + } // namespace NativeWindow::NativeWindow( @@ -559,6 +578,15 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) { return handled; } +void NativeWindow::UpdateDraggableRegions( + const std::vector& regions) { + // Draggable region is not supported for non-frameless window. + if (has_frame_) + return; + + draggable_region_.reset(DraggableRegionsToSkRegion(regions)); +} + void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index b9c2486b791b..611ff82011c5 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -23,6 +23,8 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" +class SkRegion; + namespace base { class CommandLine; } @@ -217,6 +219,7 @@ class NativeWindow : public content::WebContentsObserver, } bool has_frame() const { return has_frame_; } + SkRegion* draggable_region() const { return draggable_region_.get(); } void set_has_dialog_attached(bool has_dialog_attached) { has_dialog_attached_ = has_dialog_attached; @@ -226,10 +229,6 @@ class NativeWindow : public content::WebContentsObserver, NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); - // Called when the window needs to update its draggable region. - virtual void UpdateDraggableRegions( - const std::vector& regions) = 0; - // brightray::InspectableWebContentsViewDelegate: void DevToolsFocused() override; void DevToolsOpened() override; @@ -257,6 +256,10 @@ class NativeWindow : public content::WebContentsObserver, ObserverList observers_; private: + // Called when the window needs to update its draggable region. + void UpdateDraggableRegions( + const std::vector& regions); + // Schedule a notification unresponsive event. void ScheduleUnresponsiveEvent(int ms); @@ -298,6 +301,10 @@ class NativeWindow : public content::WebContentsObserver, // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; + // For custom drag, the whole window is non-draggable and the draggable region + // has to been explicitly provided. + scoped_ptr draggable_region_; // used in custom drag. + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(NativeWindow); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 67f4389ff703..e54dc6ad87f6 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -11,13 +11,11 @@ #include #include "base/mac/scoped_nsobject.h" -#include "base/memory/scoped_ptr.h" #include "atom/browser/native_window.h" @class AtomNSWindow; @class AtomNSWindowDelegate; @class FullSizeContentView; -class SkRegion; namespace atom { @@ -88,9 +86,6 @@ class NativeWindowMac : public NativeWindow { void ClipWebView(); protected: - void UpdateDraggableRegions( - const std::vector& regions) override; - // NativeWindow: void HandleKeyboardEvent( content::WebContents*, @@ -117,10 +112,6 @@ class NativeWindowMac : public NativeWindow { // The presentation options before entering kiosk mode. NSApplicationPresentationOptions kiosk_options_; - // For custom drag, the whole window is non-draggable and the draggable region - // has to been explicitly provided. - scoped_ptr draggable_region_; // used in custom drag. - // Mouse location since the last mouse event, in screen coordinates. This is // used in custom drag to compute the window movement. NSPoint last_mouse_offset_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 295c0ac5400a..8a0955b2903c 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -318,29 +318,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; namespace atom { -namespace { - -// Convert draggable regions in raw format to SkRegion format. Caller is -// responsible for deleting the returned SkRegion instance. -SkRegion* DraggableRegionsToSkRegion( - const std::vector& regions) { - SkRegion* sk_region = new SkRegion; - for (std::vector::const_iterator iter = regions.begin(); - iter != regions.end(); - ++iter) { - const DraggableRegion& region = *iter; - sk_region->op( - region.bounds.x(), - region.bounds.y(), - region.bounds.right(), - region.bounds.bottom(), - region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); - } - return sk_region; -} - -} // namespace - NativeWindowMac::NativeWindowMac( brightray::InspectableWebContents* web_contents, const mate::Dictionary& options) @@ -747,7 +724,7 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() { } bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const { - if (!draggable_region_) + if (!draggable_region()) return false; if (!web_contents()) return false; @@ -756,7 +733,7 @@ bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const { // |draggable_region_| is stored in local platform-indepdent coordiate system // while |point| is in local Cocoa coordinate system. Do the conversion // to match these two. - return draggable_region_->contains(point.x, webViewHeight - point.y); + return draggable_region()->contains(point.x, webViewHeight - point.y); } void NativeWindowMac::HandleMouseEvent(NSEvent* event) { @@ -776,15 +753,6 @@ void NativeWindowMac::HandleMouseEvent(NSEvent* event) { } } -void NativeWindowMac::UpdateDraggableRegions( - const std::vector& regions) { - // Draggable region is not supported for non-frameless window. - if (has_frame_) - return; - - draggable_region_.reset(DraggableRegionsToSkRegion(regions)); -} - void NativeWindowMac::HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 62cf51f4d84e..35aea41eb549 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -753,29 +753,6 @@ gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() { return GetNativeWindow()->GetHost()->GetAcceleratedWidget(); } -void NativeWindowViews::UpdateDraggableRegions( - const std::vector& regions) { - if (has_frame_) - return; - - SkRegion* draggable_region = new SkRegion; - - // By default, the whole window is non-draggable. We need to explicitly - // include those draggable regions. - for (std::vector::const_iterator iter = regions.begin(); - iter != regions.end(); ++iter) { - const DraggableRegion& region = *iter; - draggable_region->op( - region.bounds.x(), - region.bounds.y(), - region.bounds.right(), - region.bounds.bottom(), - region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); - } - - draggable_region_.reset(draggable_region); -} - void NativeWindowViews::OnWidgetActivationChanged( views::Widget* widget, bool active) { if (widget != window_.get()) @@ -858,8 +835,8 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling( gfx::NativeView child, const gfx::Point& location) { // App window should claim mouse events that fall within the draggable region. - if (draggable_region_ && - draggable_region_->contains(location.x(), location.y())) + if (draggable_region() && + draggable_region()->contains(location.x(), location.y())) return false; // And the events on border for dragging resizable frameless window. diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index fa7e13c1c335..dcf1f603a4f4 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -82,14 +82,9 @@ class NativeWindowViews : public NativeWindow, gfx::AcceleratedWidget GetAcceleratedWidget(); - SkRegion* draggable_region() const { return draggable_region_.get(); } views::Widget* widget() const { return window_.get(); } private: - // NativeWindow: - void UpdateDraggableRegions( - const std::vector& regions) override; - // views::WidgetObserver: void OnWidgetActivationChanged( views::Widget* widget, bool active) override; @@ -177,8 +172,6 @@ class NativeWindowViews : public NativeWindow, gfx::Size maximum_size_; gfx::Size widget_size_; - scoped_ptr draggable_region_; - DISALLOW_COPY_AND_ASSIGN(NativeWindowViews); }; From 438a5acc0f7eefd90b706fbf276a99dae5a43d26 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 12:34:45 +0800 Subject: [PATCH 118/172] Use ranged for loop --- atom/browser/native_window.cc | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c9d68df640a5..0461b7d74eb8 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -70,13 +70,10 @@ const char* kWebRuntimeFeatures[] = { // Convert draggable regions in raw format to SkRegion format. Caller is // responsible for deleting the returned SkRegion instance. -SkRegion* DraggableRegionsToSkRegion( +scoped_ptr DraggableRegionsToSkRegion( const std::vector& regions) { - SkRegion* sk_region = new SkRegion; - for (std::vector::const_iterator iter = regions.begin(); - iter != regions.end(); - ++iter) { - const DraggableRegion& region = *iter; + scoped_ptr sk_region(new SkRegion); + for (const DraggableRegion& region : regions) { sk_region->op( region.bounds.x(), region.bounds.y(), @@ -84,7 +81,7 @@ SkRegion* DraggableRegionsToSkRegion( region.bounds.bottom(), region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); } - return sk_region; + return sk_region.Pass(); } } // namespace @@ -583,8 +580,7 @@ void NativeWindow::UpdateDraggableRegions( // Draggable region is not supported for non-frameless window. if (has_frame_) return; - - draggable_region_.reset(DraggableRegionsToSkRegion(regions)); + draggable_region_ = DraggableRegionsToSkRegion(regions); } void NativeWindow::ScheduleUnresponsiveEvent(int ms) { From 58b1172025ad754939aeefe7af2f2fe4b3e225ea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 12:46:32 +0800 Subject: [PATCH 119/172] Avoid exposing data members to subclass --- atom/browser/native_window.cc | 6 +++++ atom/browser/native_window.h | 41 ++++++++++++++++------------- atom/browser/native_window_mac.mm | 18 ++++++------- atom/browser/native_window_views.cc | 34 +++++++++++------------- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 0461b7d74eb8..96085846bca8 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -522,6 +522,12 @@ void NativeWindow::NotifyWindowLeaveHtmlFullScreen() { OnWindowLeaveHtmlFullScreen()); } +void NativeWindow::NotifyWindowExecuteWindowsCommand( + const std::string& command) { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnExecuteWindowsCommand(command)); +} + void NativeWindow::DevToolsFocused() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus()); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 611ff82011c5..8919d529df03 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -205,11 +205,11 @@ class NativeWindow : public content::WebContentsObserver, void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); void NotifyWindowLeaveHtmlFullScreen(); + void NotifyWindowExecuteWindowsCommand(const std::string& command); void AddObserver(NativeWindowObserver* obs) { observers_.AddObserver(obs); } - void RemoveObserver(NativeWindowObserver* obs) { observers_.RemoveObserver(obs); } @@ -219,7 +219,10 @@ class NativeWindow : public content::WebContentsObserver, } bool has_frame() const { return has_frame_; } + bool transparent() const { return transparent_; } SkRegion* draggable_region() const { return draggable_region_.get(); } + bool enable_larger_than_screen() const { return enable_larger_than_screen_; } + gfx::ImageSkia icon() const { return icon_; } void set_has_dialog_attached(bool has_dialog_attached) { has_dialog_attached_ = has_dialog_attached; @@ -240,21 +243,6 @@ class NativeWindow : public content::WebContentsObserver, void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; - // Whether window has standard frame. - bool has_frame_; - - // Whether window is transparent. - bool transparent_; - - // Whether window can be resized larger than screen. - bool enable_larger_than_screen_; - - // Window icon. - gfx::ImageSkia icon_; - - // Observers of this window. - ObserverList observers_; - private: // Called when the window needs to update its draggable region. void UpdateDraggableRegions( @@ -271,6 +259,22 @@ class NativeWindow : public content::WebContentsObserver, const SkBitmap& bitmap, content::ReadbackResponse response); + // Whether window has standard frame. + bool has_frame_; + + // Whether window is transparent. + bool transparent_; + + // For custom drag, the whole window is non-draggable and the draggable region + // has to been explicitly provided. + scoped_ptr draggable_region_; // used in custom drag. + + // Whether window can be resized larger than screen. + bool enable_larger_than_screen_; + + // Window icon. + gfx::ImageSkia icon_; + // The windows has been closed. bool is_closed_; @@ -301,9 +305,8 @@ class NativeWindow : public content::WebContentsObserver, // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; - // For custom drag, the whole window is non-draggable and the draggable region - // has to been explicitly provided. - scoped_ptr draggable_region_; // used in custom drag. + // Observers of this window. + ObserverList observers_; base::WeakPtrFactory weak_factory_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 8a0955b2903c..d9ac903590f2 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -340,7 +340,7 @@ NativeWindowMac::NativeWindowMac( NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask; - if (!useStandardWindow || transparent_ || !has_frame_) { + if (!useStandardWindow || transparent() || !has_frame()) { styleMask |= NSTexturedBackgroundWindowMask; } @@ -350,12 +350,12 @@ NativeWindowMac::NativeWindowMac( backing:NSBackingStoreBuffered defer:YES]); [window_ setShell:this]; - [window_ setEnableLargerThanScreen:enable_larger_than_screen_]; + [window_ setEnableLargerThanScreen:enable_larger_than_screen()]; window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]); [window_ setDelegate:window_delegate_]; - if (transparent_) { + if (transparent()) { // Make window has transparent background. [window_ setOpaque:NO]; [window_ setHasShadow:NO]; @@ -363,7 +363,7 @@ NativeWindowMac::NativeWindowMac( } // Remove non-transparent corners, see http://git.io/vfonD. - if (!has_frame_) + if (!has_frame()) [window_ setOpaque:NO]; // We will manage window's lifetime ourselves. @@ -372,7 +372,7 @@ NativeWindowMac::NativeWindowMac( // On OS X the initial window size doesn't include window frame. bool use_content_size = false; options.Get(switches::kUseContentSize, &use_content_size); - if (!has_frame_ || !use_content_size) + if (!has_frame() || !use_content_size) SetSize(gfx::Size(width, height)); // Enable the NSView to accept first mouse event. @@ -509,7 +509,7 @@ gfx::Rect NativeWindowMac::GetBounds() { } void NativeWindowMac::SetContentSize(const gfx::Size& size) { - if (!has_frame_) { + if (!has_frame()) { SetSize(size); return; } @@ -527,7 +527,7 @@ void NativeWindowMac::SetContentSize(const gfx::Size& size) { } gfx::Size NativeWindowMac::GetContentSize() { - if (!has_frame_) + if (!has_frame()) return GetSize(); NSRect bounds = [[window_ contentView] bounds]; @@ -588,7 +588,7 @@ void NativeWindowMac::Center() { void NativeWindowMac::SetTitle(const std::string& title) { // We don't want the title to show in transparent window. - if (transparent_) + if (transparent()) return; [window_ setTitle:base::SysUTF8ToNSString(title)]; @@ -779,7 +779,7 @@ void NativeWindowMac::HandleKeyboardEvent( void NativeWindowMac::InstallView() { NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); - if (has_frame_) { + if (has_frame()) { // Add layer with white background for the contents view. base::scoped_nsobject layer([[CALayer alloc] init]); [layer setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 35aea41eb549..cb28f2dd9871 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -232,7 +232,7 @@ NativeWindowViews::NativeWindowViews( options.Get(switches::kResizable, &resizable_); #endif - if (enable_larger_than_screen_) + if (enable_larger_than_screen()) // We need to set a default maximum window size here otherwise Windows // will not allow us to resize the window larger than scree. // Setting directly to INT_MAX somehow doesn't work, so we just devide @@ -252,9 +252,9 @@ NativeWindowViews::NativeWindowViews( params.bounds = bounds; params.delegate = this; params.type = views::Widget::InitParams::TYPE_WINDOW; - params.remove_standard_frame = !has_frame_; + params.remove_standard_frame = !has_frame(); - if (transparent_) + if (transparent()) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; #if defined(USE_X11) @@ -312,24 +312,24 @@ NativeWindowViews::NativeWindowViews( set_background(views::Background::CreateStandardPanelBackground()); AddChildView(web_view_); - if (has_frame_ && + if (has_frame() && options.Get(switches::kUseContentSize, &use_content_size_) && use_content_size_) bounds = ContentBoundsToWindowBounds(bounds); #if defined(OS_WIN) - if (!has_frame_) { + if (!has_frame()) { // Set Window style so that we get a minimize and maximize animation when // frameless. DWORD frame_style = WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION; // We should not show a frame for transparent window. - if (transparent_) + if (transparent()) frame_style &= ~(WS_THICKFRAME | WS_CAPTION); ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); } - if (transparent_) { + if (transparent()) { // Transparent window on Windows has to have WS_EX_COMPOSITED style. LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); ex_style |= WS_EX_COMPOSITED; @@ -339,14 +339,14 @@ NativeWindowViews::NativeWindowViews( // TODO(zcbenz): This was used to force using native frame on Windows 2003, we // should check whether setting it in InitParams can work. - if (has_frame_) { + if (has_frame()) { window_->set_frame_type(views::Widget::FrameType::FRAME_TYPE_FORCE_NATIVE); window_->FrameTypeChanged(); } // The given window is most likely not rectangular since it uses // transparency and has no standard frame, don't show a shadow for it. - if (transparent_ && !has_frame_) + if (transparent() && !has_frame()) wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); window_->UpdateWindowIcon(); @@ -469,7 +469,7 @@ gfx::Rect NativeWindowViews::GetBounds() { } void NativeWindowViews::SetContentSize(const gfx::Size& size) { - if (!has_frame_) { + if (!has_frame()) { NativeWindow::SetSize(size); return; } @@ -480,7 +480,7 @@ void NativeWindowViews::SetContentSize(const gfx::Size& size) { } gfx::Size NativeWindowViews::GetContentSize() { - if (!has_frame_) + if (!has_frame()) return GetSize(); gfx::Size content_size = @@ -628,7 +628,7 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { #endif // Do not show menu bar in frameless window. - if (!has_frame_) + if (!has_frame()) return; if (!menu_bar_) { @@ -812,7 +812,7 @@ bool NativeWindowViews::ShouldHandleSystemCommands() const { } gfx::ImageSkia NativeWindowViews::GetWindowAppIcon() { - return icon_; + return icon(); } gfx::ImageSkia NativeWindowViews::GetWindowIcon() { @@ -840,7 +840,7 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling( return false; // And the events on border for dragging resizable frameless window. - if (!has_frame_ && CanResize()) { + if (!has_frame() && CanResize()) { FramelessView* frame = static_cast( window_->non_client_view()->frame_view()); return frame->ResizingBorderHitTest(location) == HTNOWHERE; @@ -860,7 +860,7 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView( frame_view->Init(this, widget); return frame_view; #else - if (has_frame_) { + if (has_frame()) { return new NativeFrameView(this, widget); } else { FramelessView* frame_view = new FramelessView; @@ -892,9 +892,7 @@ bool NativeWindowViews::ExecuteWindowsCommand(int command_id) { NotifyWindowMaximize(); } else { std::string command = AppCommandToString(command_id); - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - OnExecuteWindowsCommand(command)); + NotifyWindowExecuteWindowsCommand(command); } return false; } From adbb909b39238254b55f12ab432de380adb1ae0c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 13:16:03 +0800 Subject: [PATCH 120/172] Move ShouldUseGlobalMenuBar to x_window_utils --- atom/browser/native_window_views.cc | 39 ----------------------------- atom/browser/ui/x/x_window_utils.cc | 36 ++++++++++++++++++++++++++ atom/browser/ui/x/x_window_utils.h | 3 +++ 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index cb28f2dd9871..63867111040f 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -43,9 +43,6 @@ #include "base/nix/xdg_util.h" #include "base/strings/string_util.h" #include "chrome/browser/ui/libgtk2ui/unity_service.h" -#include "dbus/bus.h" -#include "dbus/object_proxy.h" -#include "dbus/message.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/x/x11_types.h" #include "ui/views/window/native_frame_view.h" @@ -70,42 +67,6 @@ const int kMenuBarHeight = 20; const int kMenuBarHeight = 25; #endif -#if defined(USE_X11) -// Returns true if the bus name "com.canonical.AppMenu.Registrar" is available. -bool ShouldUseGlobalMenuBar() { - dbus::Bus::Options options; - scoped_refptr bus(new dbus::Bus(options)); - - dbus::ObjectProxy* object_proxy = - bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS)); - dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, "ListNames"); - scoped_ptr response(object_proxy->CallMethodAndBlock( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); - if (!response) { - bus->ShutdownAndBlock(); - return false; - } - - dbus::MessageReader reader(response.get()); - dbus::MessageReader array_reader(NULL); - if (!reader.PopArray(&array_reader)) { - bus->ShutdownAndBlock(); - return false; - } - while (array_reader.HasMoreData()) { - std::string name; - if (array_reader.PopString(&name) && - name == "com.canonical.AppMenu.Registrar") { - bus->ShutdownAndBlock(); - return true; - } - } - - bus->ShutdownAndBlock(); - return false; -} -#endif - bool IsAltKey(const content::NativeWebKeyboardEvent& event) { #if defined(USE_X11) // 164 and 165 represent VK_LALT and VK_RALT. diff --git a/atom/browser/ui/x/x_window_utils.cc b/atom/browser/ui/x/x_window_utils.cc index eaef5475b777..a15affb05f1b 100644 --- a/atom/browser/ui/x/x_window_utils.cc +++ b/atom/browser/ui/x/x_window_utils.cc @@ -7,6 +7,9 @@ #include #include "base/strings/string_util.h" +#include "dbus/bus.h" +#include "dbus/object_proxy.h" +#include "dbus/message.h" #include "ui/base/x/x11_util.h" namespace atom { @@ -46,4 +49,37 @@ void SetWindowType(::Window xwindow, const std::string& type) { reinterpret_cast(&window_type), 1); } +bool ShouldUseGlobalMenuBar() { + dbus::Bus::Options options; + scoped_refptr bus(new dbus::Bus(options)); + + dbus::ObjectProxy* object_proxy = + bus->GetObjectProxy(DBUS_SERVICE_DBUS, dbus::ObjectPath(DBUS_PATH_DBUS)); + dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, "ListNames"); + scoped_ptr response(object_proxy->CallMethodAndBlock( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); + if (!response) { + bus->ShutdownAndBlock(); + return false; + } + + dbus::MessageReader reader(response.get()); + dbus::MessageReader array_reader(NULL); + if (!reader.PopArray(&array_reader)) { + bus->ShutdownAndBlock(); + return false; + } + while (array_reader.HasMoreData()) { + std::string name; + if (array_reader.PopString(&name) && + name == "com.canonical.AppMenu.Registrar") { + bus->ShutdownAndBlock(); + return true; + } + } + + bus->ShutdownAndBlock(); + return false; +} + } // namespace atom diff --git a/atom/browser/ui/x/x_window_utils.h b/atom/browser/ui/x/x_window_utils.h index ccf56d1eb9cf..16f3ddac6ccd 100644 --- a/atom/browser/ui/x/x_window_utils.h +++ b/atom/browser/ui/x/x_window_utils.h @@ -22,6 +22,9 @@ void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state); // Sets the _NET_WM_WINDOW_TYPE of window. void SetWindowType(::Window xwindow, const std::string& type); +// Returns true if the bus name "com.canonical.AppMenu.Registrar" is available. +bool ShouldUseGlobalMenuBar(); + } // namespace atom #endif // ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_ From bbd6c927b1e3a146ce78787c5ea8fb6227466608 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 13:18:41 +0800 Subject: [PATCH 121/172] Remove a few unused headers --- atom/browser/native_window_views.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 63867111040f..5f3472a7ffdb 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -20,7 +20,6 @@ #include "brightray/browser/inspectable_web_contents_view.h" #include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" -#include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/hit_test.h" #include "ui/gfx/image/image.h" @@ -39,8 +38,6 @@ #include "atom/browser/ui/views/native_frame_view.h" #include "atom/browser/ui/x/window_state_watcher.h" #include "atom/browser/ui/x/x_window_utils.h" -#include "base/environment.h" -#include "base/nix/xdg_util.h" #include "base/strings/string_util.h" #include "chrome/browser/ui/libgtk2ui/unity_service.h" #include "ui/base/x/x11_util.h" From 54af048f04c3194530081c56e10c567a14195339 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 2 Aug 2015 11:11:29 +0800 Subject: [PATCH 122/172] win: Add BrowserWindow.setThumbarButtons API. --- atom/browser/api/atom_api_window.cc | 34 +++++ atom/browser/api/atom_api_window.h | 8 ++ .../atom_desktop_window_tree_host_win.cc | 44 +++++++ .../atom_desktop_window_tree_host_win.h | 41 ++++++ atom/browser/native_window.h | 8 ++ atom/browser/native_window_views.cc | 22 ++++ atom/browser/native_window_views.h | 9 ++ atom/browser/ui/win/thumbar_host.cc | 122 ++++++++++++++++++ atom/browser/ui/win/thumbar_host.h | 51 ++++++++ filenames.gypi | 4 + 10 files changed, 343 insertions(+) create mode 100644 atom/browser/atom_desktop_window_tree_host_win.cc create mode 100644 atom/browser/atom_desktop_window_tree_host_win.h create mode 100644 atom/browser/ui/win/thumbar_host.cc create mode 100644 atom/browser/ui/win/thumbar_host.h diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 5f7c2503fced..bcdc57c3c704 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -20,6 +20,30 @@ #include "atom/common/node_includes.h" +#if defined(OS_WIN) +#include "atom/browser/ui/win/thumbar_host.h" +#endif + +namespace mate { + +#if defined(OS_WIN) +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + atom::ThumbarHost::ThumbarButton* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + dict.Get("click", &(out->clicked_callback)); + dict.Get("tooltip", &(out->tooltip)); + dict.Get("flags", &out->flags); + return dict.Get("icon", &(out->icon)); + } +}; +#endif + +} // namespace mate + namespace atom { namespace api { @@ -413,6 +437,13 @@ void Window::SetOverlayIcon(const gfx::Image& overlay, window_->SetOverlayIcon(overlay, description); } +#if defined(OS_WIN) +void Window::SetThumbarButtons( + const std::vector& buttons) { + window_->SetThumbarButtons(buttons); +} +#endif + void Window::SetMenu(v8::Isolate* isolate, v8::Local value) { mate::Handle menu; if (value->IsObject() && @@ -538,6 +569,9 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("capturePage", &Window::CapturePage) .SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon) +#if defined(OS_WIN) + .SetMethod("setThumbarButtons", &Window::SetThumbarButtons) +#endif .SetMethod("setMenu", &Window::SetMenu) .SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar) .SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index cc2b3a64b5e9..fdb10825a6ca 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -14,6 +14,10 @@ #include "atom/browser/native_window_observer.h" #include "native_mate/handle.h" +#if defined(OS_WIN) +#include "atom/browser/ui/win/thumbar_host.h" +#endif + class GURL; namespace gfx { @@ -129,6 +133,10 @@ class Window : public mate::TrackableObject, void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); +#if defined(OS_WIN) + void SetThumbarButtons( + const std::vector& buttons); +#endif void SetMenu(v8::Isolate* isolate, v8::Local menu); void SetAutoHideMenuBar(bool auto_hide); bool IsMenuBarAutoHide(); diff --git a/atom/browser/atom_desktop_window_tree_host_win.cc b/atom/browser/atom_desktop_window_tree_host_win.cc new file mode 100644 index 000000000000..9c5ebf0f42c2 --- /dev/null +++ b/atom/browser/atom_desktop_window_tree_host_win.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/atom_desktop_window_tree_host_win.h" +#include "atom/browser/ui/win/thumbar_host.h" + +namespace atom { + +AtomDesktopWindowTreeHostWin::AtomDesktopWindowTreeHostWin( + views::internal::NativeWidgetDelegate* native_widget_delegate, + views::DesktopNativeWidgetAura* desktop_native_widget_aura) + : views::DesktopWindowTreeHostWin(native_widget_delegate, + desktop_native_widget_aura) { +} + +AtomDesktopWindowTreeHostWin::~AtomDesktopWindowTreeHostWin() { +} + +bool AtomDesktopWindowTreeHostWin::SetThumbarButtons( + HWND window, + const std::vector& buttons) { + if (!thumbar_host_.get()) { + thumbar_host_.reset(new ThumbarHost(window)); + } + return thumbar_host_->SetThumbarButtons(buttons); +} + +bool AtomDesktopWindowTreeHostWin::PreHandleMSG(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) { + switch (message) { + case WM_COMMAND: { + int id = LOWORD(w_param); + if (thumbar_host_ && thumbar_host_->HandleThumbarButtonEvent(id)) + return true; + } + } + + return false; +} + +} // namespace atom diff --git a/atom/browser/atom_desktop_window_tree_host_win.h b/atom/browser/atom_desktop_window_tree_host_win.h new file mode 100644 index 000000000000..0271d06e6af2 --- /dev/null +++ b/atom/browser/atom_desktop_window_tree_host_win.h @@ -0,0 +1,41 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ +#define ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ + +#include + +#include + +#include "atom/browser/ui/win/thumbar_host.h" +#include "base/memory/scoped_ptr.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" + +namespace atom { + +class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { + public: + AtomDesktopWindowTreeHostWin( + views::internal::NativeWidgetDelegate* native_widget_delegate, + views::DesktopNativeWidgetAura* desktop_native_widget_aura); + ~AtomDesktopWindowTreeHostWin(); + + bool SetThumbarButtons( + HWND window, + const std::vector& buttons); + + protected: + bool PreHandleMSG(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) override; + + private: + scoped_ptr thumbar_host_; +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 8919d529df03..0ae22214f563 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -23,6 +23,10 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" +#if defined(OS_WIN) +#include "atom/browser/ui/win/thumbar_host.h" +#endif + class SkRegion; namespace base { @@ -144,6 +148,10 @@ class NativeWindow : public content::WebContentsObserver, const std::string& description) = 0; virtual void SetVisibleOnAllWorkspaces(bool visible) = 0; virtual bool IsVisibleOnAllWorkspaces() = 0; +#if defined(OS_WIN) + virtual bool SetThumbarButtons( + const std::vector& buttons) = 0; +#endif virtual bool IsClosed() const { return is_closed_; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 5f3472a7ffdb..e0221fbde597 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -27,6 +27,7 @@ #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/window/client_view.h" +#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/native_widget_private.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/shadow_types.h" @@ -44,6 +45,7 @@ #include "ui/gfx/x/x11_types.h" #include "ui/views/window/native_frame_view.h" #elif defined(OS_WIN) +#include "atom/browser/atom_desktop_window_tree_host_win.h" #include "atom/browser/ui/views/win_frame_view.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" @@ -215,6 +217,14 @@ NativeWindowViews::NativeWindowViews( if (transparent()) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; +#if defined(OS_WIN) + params.native_widget = + new views::DesktopNativeWidgetAura(window_.get()); + atom_desktop_window_tree_host_win_ = new AtomDesktopWindowTreeHostWin( + window_.get(), + static_cast(params.native_widget)); + params.desktop_window_tree_host = atom_desktop_window_tree_host_win_; +#endif #if defined(USE_X11) std::string name = Browser::Get()->GetName(); // Set WM_WINDOW_ROLE. @@ -707,6 +717,18 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() { return false; } +#if defined(OS_WIN) +bool NativeWindowViews::SetThumbarButtons( + const std::vector& buttons) { + if (atom_desktop_window_tree_host_win_) { + return atom_desktop_window_tree_host_win_->SetThumbarButtons( + views::HWNDForNativeWindow(window_->GetNativeWindow()), + buttons); + } + return false; +} +#endif + gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() { return GetNativeWindow()->GetHost()->GetAcceleratedWidget(); } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index dcf1f603a4f4..94c0c04373f7 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -23,6 +23,9 @@ namespace atom { class GlobalMenuBarX11; class MenuBar; class WindowStateWatcher; +#if defined(OS_WIN) +class AtomDesktopWindowTreeHostWin; +#endif class NativeWindowViews : public NativeWindow, public views::WidgetDelegateView, @@ -79,6 +82,10 @@ class NativeWindowViews : public NativeWindow, bool IsMenuBarVisible() override; void SetVisibleOnAllWorkspaces(bool visible) override; bool IsVisibleOnAllWorkspaces() override; +#if defined(OS_WIN) + bool SetThumbarButtons( + const std::vector& buttons) override; +#endif gfx::AcceleratedWidget GetAcceleratedWidget(); @@ -154,6 +161,8 @@ class NativeWindowViews : public NativeWindow, // Handles window state events. scoped_ptr window_state_watcher_; #elif defined(OS_WIN) + // Weak ref. + AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_; // Records window was whether restored from minimized state or maximized // state. bool is_minimized_; diff --git a/atom/browser/ui/win/thumbar_host.cc b/atom/browser/ui/win/thumbar_host.cc new file mode 100644 index 000000000000..22e9ba8c4169 --- /dev/null +++ b/atom/browser/ui/win/thumbar_host.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/win/thumbar_host.h" + +#include + +#include "base/win/scoped_comptr.h" +#include "base/win/win_util.h" +#include "base/win/wrapped_window_proc.h" +#include "base/strings/utf_string_conversions.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/icon_util.h" +#include "ui/gfx/win/hwnd_util.h" + +namespace atom { + +namespace { + +// The thumbnail toolbar has a maximum of seven buttons due to the limited room. +const int kMaxButtonsCount = 7; + +bool GetThumbarButtonFlags(const std::vector& flags, + THUMBBUTTONFLAGS* out) { + if (flags.empty()) { + *out = THBF_ENABLED; + return true; + } + THUMBBUTTONFLAGS result = static_cast(0); + for (const auto& flag : flags) { + if (flag == "enabled") { + result |= THBF_ENABLED; + } else if (flag == "disabled") { + result |= THBF_DISABLED; + } else if (flag == "dismissonclick") { + result |= THBF_DISMISSONCLICK; + } else if (flag == "nobackground") { + result |= THBF_NOBACKGROUND; + } else if (flag == "hidden") { + result |= THBF_HIDDEN; + } else if (flag == "noninteractive") { + result |= THBF_NONINTERACTIVE; + } else { + return false; + } + } + *out = result; + return true; +} + +} // namespace + +ThumbarHost::ThumbarHost(HWND window) : is_initialized_(false), + window_(window) { +} + +ThumbarHost::~ThumbarHost() { +} + +bool ThumbarHost::SetThumbarButtons( + const std::vector& buttons) { + THUMBBUTTON thumb_buttons[kMaxButtonsCount]; + thumbar_button_clicked_callback_map_.clear(); + + // Once a toolbar with a set of buttons is added to thumbnail, there is no way + // to remove it without re-creating the window. + // To achieve to re-set thumbar buttons, we initialize the buttons with + // HIDDEN state and only updated the caller's specified buttons. + // + // Initialize all thumb buttons with HIDDEN state. + for (int i = 0; i < kMaxButtonsCount; ++i) { + thumb_buttons[i].iId = i; + thumb_buttons[i].dwFlags = THBF_HIDDEN; + } + + // Update the callers' specified buttons. + for (size_t i = 0; i < buttons.size(); ++i) { + if (!GetThumbarButtonFlags(buttons[i].flags, &thumb_buttons[i].dwFlags)) + return false; + thumb_buttons[i].dwMask = THB_ICON | THB_FLAGS; + thumb_buttons[i].hIcon = IconUtil::CreateHICONFromSkBitmap( + buttons[i].icon.AsBitmap()); + if (!buttons[i].tooltip.empty()) { + thumb_buttons[i].dwMask |= THB_TOOLTIP; + wcscpy_s(thumb_buttons[i].szTip, + base::UTF8ToUTF16(buttons[i].tooltip).c_str()); + } + + thumbar_button_clicked_callback_map_[i] = + buttons[i].clicked_callback; + } + + base::win::ScopedComPtr taskbar; + if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, + nullptr, + CLSCTX_INPROC_SERVER)) || + FAILED(taskbar->HrInit())) { + return false; + } + if (!is_initialized_) { + is_initialized_ = true; + return taskbar->ThumbBarAddButtons( + window_, kMaxButtonsCount, thumb_buttons) == S_OK; + } + + return taskbar->ThumbBarUpdateButtons( + window_, kMaxButtonsCount, thumb_buttons) == S_OK; +} + +bool ThumbarHost::HandleThumbarButtonEvent(int button_id) { + if (thumbar_button_clicked_callback_map_.find(button_id) != + thumbar_button_clicked_callback_map_.end()) { + auto callback = thumbar_button_clicked_callback_map_[button_id]; + if (!callback.is_null()) + callback.Run(); + return true; + } + return false; +} + +} // namespace atom diff --git a/atom/browser/ui/win/thumbar_host.h b/atom/browser/ui/win/thumbar_host.h new file mode 100644 index 000000000000..2ab3b06a381d --- /dev/null +++ b/atom/browser/ui/win/thumbar_host.h @@ -0,0 +1,51 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ +#define ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ + +#include + +#include +#include +#include + +#include "base/callback.h" +#include "ui/gfx/image/image.h" + +namespace atom { + +class ThumbarHost { + public: + using ThumbarButtonClickedCallback = base::Callback; + + struct ThumbarButton { + std::string tooltip; + gfx::Image icon; + std::vector flags; + ThumbarButtonClickedCallback clicked_callback; + }; + + explicit ThumbarHost(HWND window); + ~ThumbarHost(); + + bool SetThumbarButtons( + const std::vector& buttons); + bool HandleThumbarButtonEvent(int button_id); + + private: + using ThumbarButtonClickedCallbackMap = std::map< + int, ThumbarButtonClickedCallback>; + ThumbarButtonClickedCallbackMap thumbar_button_clicked_callback_map_; + + bool is_initialized_; + + HWND window_; + + DISALLOW_COPY_AND_ASSIGN(ThumbarHost); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ diff --git a/filenames.gypi b/filenames.gypi index 82f9ea95d078..3b3d3a4cc48f 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -119,6 +119,8 @@ 'atom/browser/atom_browser_main_parts.h', 'atom/browser/atom_browser_main_parts_linux.cc', 'atom/browser/atom_browser_main_parts_mac.mm', + "atom/browser/atom_desktop_window_tree_host_win.cc", + "atom/browser/atom_desktop_window_tree_host_win.h", 'atom/browser/atom_javascript_dialog_manager.cc', 'atom/browser/atom_javascript_dialog_manager.h', 'atom/browser/atom_quota_permission_context.cc', @@ -206,6 +208,8 @@ 'atom/browser/ui/win/notify_icon_host.h', 'atom/browser/ui/win/notify_icon.cc', 'atom/browser/ui/win/notify_icon.h', + 'atom/browser/ui/win/thumbar_host.cc', + 'atom/browser/ui/win/thumbar_host.h', 'atom/browser/ui/x/window_state_watcher.cc', 'atom/browser/ui/x/window_state_watcher.h', 'atom/browser/ui/x/x_window_utils.cc', From 97ab780305abda01e3aacc9898e0967d798b3649 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 2 Aug 2015 13:07:55 +0800 Subject: [PATCH 123/172] :memo: BrowserWindow.setThumbarButton API. --- docs/api/browser-window.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index add5cfff8ba9..73f9c97de58d 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -643,6 +643,35 @@ Sets a 16px overlay onto the current taskbar icon, usually used to convey some s __Note:__ This API is only available on Windows (Windows 7 and above) + +### BrowserWindow.setThumbarButtons(buttons) + +* `buttons` Array of `button` objects + * `button` Object + * `icon` [NativeImage](native-image.md) - The icon showing in thumbnail toolbar. + * `tooltip` String - (Option) - The text of the button's tooltip. + * `flags` Array of Strings - (Option) Control specific states and behaviors + of the button. By default, it uses `enabled`. + * `enabled` - The button is active and available to the user. + * `disabled` - The button is disabled. It is present, but has a visual state + that indicates that it will not respond to user action. + * `dismissonclick` - When the button is clicked, the taskbar button's flyout + closes immediately. + * `nobackground` - Do not draw a button border, use only the image. + * `hidden` - The button is not shown to the user. + * `noninteractive` - The button is enabled but not interactive; no pressed + button state is drawn. This value is intended for instances where the button + is used in a notification. + * `click` - Function + +Add a thumbnail toolbar with a specified set of buttons to the thumbnail image of +a window in a taskbar button layout. + +__Note:__ This API is only available on Windows (Windows 7 and above). +Once you setup the thumbnail toolbar, the toolbar cannot be removed due to the +platform's limitation. But you can call the API with an empty array to clean the +buttons. + ### BrowserWindow.showDefinitionForSelection() Shows pop-up dictionary that searches the selected word on the page. From ad01a1731afa7d4c6f37eb960621c6baee6051b2 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sun, 2 Aug 2015 13:09:42 +0800 Subject: [PATCH 124/172] :memo: say more about thumbnail toolbar. --- .../desktop-environment-integration.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 0691b15f4091..80b4c456938b 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -134,6 +134,59 @@ The user tasks will still show even after your application closes, so the icon and program path specified for a task should exist until your application is uninstalled. +## Thumbnail Toolbars + +On Windows, you can add a thumbnail toolbar with specified buttons in a taskbar +layout of an application window. It provides users a way to access to a particualr +window's command without restoring or activating the window. + +From MSDN, it's illustrated: + +> This toolbar is simply the familiar standard toolbar common control. It has a +> maximum of seven buttons. Each button's ID, image, tooltip, and state are defined +> in a structure, which is then passed to the taskbar. The application can show, +> enable, disable, or hide buttons from the thumbnail toolbar as required by its +> current state. +> +> For example, Windows Media Player might offer standard media transport controls +> such as play, pause, mute, and stop. + +__Thumbnail toolbar of Windows Media Player:__ + +![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png) + +You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set thumbnail +toolbar in your application: + +``` +var BrowserWindow = require('browser-window'); +var path = require('path'); +var win = new BrowserWindow({ + width: 800, + height: 600 +}); +win.setThumbarButtons([ + { + tooltip: "button1", + icon: path.join(__dirname, 'button1.png'), + click: function() { console.log("button2 clicked"); } + }, + { + tooltip: "button2", + icon: path.join(__dirname, 'button2.png'), + flags:['enabled', 'dismissonclick'], + click: function() { console.log("button2 clicked."); } + } +]); +``` + +To clean thumbnail toolbar buttons, just call `BrowserWindow.setThumbarButtons` +with an empty array: + +```javascript +win.setThumbarButtons([]); +``` + ## Unity launcher shortcuts (Linux) In Unity, you can add custom entries to its launcher via modifying `.desktop` @@ -199,3 +252,4 @@ window.setDocumentEdited(true); [setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher +[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons From dfd076a3e5e364dfa0e1b02ad9d77ecc293bdd55 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 5 Aug 2015 13:04:21 +0800 Subject: [PATCH 125/172] Move atom_desktop_window_tree_host_win to atom/browser/ui/win directory. --- atom/browser/native_window_views.cc | 2 +- .../{ => ui/win}/atom_desktop_window_tree_host_win.cc | 2 +- .../{ => ui/win}/atom_desktop_window_tree_host_win.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename atom/browser/{ => ui/win}/atom_desktop_window_tree_host_win.cc (95%) rename atom/browser/{ => ui/win}/atom_desktop_window_tree_host_win.h (83%) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e0221fbde597..018f294b8df1 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -45,8 +45,8 @@ #include "ui/gfx/x/x11_types.h" #include "ui/views/window/native_frame_view.h" #elif defined(OS_WIN) -#include "atom/browser/atom_desktop_window_tree_host_win.h" #include "atom/browser/ui/views/win_frame_view.h" +#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "ui/base/win/shell.h" diff --git a/atom/browser/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc similarity index 95% rename from atom/browser/atom_desktop_window_tree_host_win.cc rename to atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index 9c5ebf0f42c2..55912612ebba 100644 --- a/atom/browser/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "atom/browser/atom_desktop_window_tree_host_win.h" +#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" #include "atom/browser/ui/win/thumbar_host.h" namespace atom { diff --git a/atom/browser/atom_desktop_window_tree_host_win.h b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h similarity index 83% rename from atom/browser/atom_desktop_window_tree_host_win.h rename to atom/browser/ui/win/atom_desktop_window_tree_host_win.h index 0271d06e6af2..7f2abf801ad3 100644 --- a/atom/browser/atom_desktop_window_tree_host_win.h +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ -#define ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ +#ifndef ATOM_BROWSER_UI_WIN_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ +#define ATOM_BROWSER_UI_WIN_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ #include @@ -38,4 +38,4 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { } // namespace atom -#endif // ATOM_BROWSER_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ +#endif // ATOM_BROWSER_UI_WIN_ATOM_DESKTOP_WINDOW_TREE_HOST_WIN_H_ From 1505dc207be7a9b633ce6b8f5cc94c876875ff2c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 14:12:55 +0800 Subject: [PATCH 126/172] mac: Disable resizing window when changing style mask --- atom/browser/native_window_mac.mm | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index d9ac903590f2..b0649c4a80cf 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -20,7 +20,26 @@ #include "content/public/browser/render_widget_host_view.h" #include "native_mate/dictionary.h" -static const CGFloat kAtomWindowCornerRadius = 4.0; +namespace { + +// The radius of rounded corner. +const CGFloat kAtomWindowCornerRadius = 4.0; + +// Prevents window from resizing during the scope. +class ScopedDisableResize { + public: + ScopedDisableResize() { disable_resize_ = true; } + ~ScopedDisableResize() { disable_resize_ = false; } + + static bool IsResizeDisabled() { return disable_resize_; } + + private: + static bool disable_resize_; +}; + +bool ScopedDisableResize::disable_resize_ = false; + +} // namespace @interface NSView (PrivateMethods) - (CGFloat)roundedCornerRadius; @@ -214,8 +233,12 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; enable_larger_than_screen_ = enable; } -// Enable the window to be larger than screen. - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen { + // Resizing is disabled. + if (ScopedDisableResize::IsResizeDisabled()) + return [self frame]; + + // Enable the window to be larger than screen. if (enable_larger_than_screen_) return frameRect; else @@ -561,6 +584,9 @@ gfx::Size NativeWindowMac::GetMaximumSize() { } void NativeWindowMac::SetResizable(bool resizable) { + // Change styleMask for frameless causes the window to change size, so we have + // to explicitly disables that. + ScopedDisableResize disable_resize; if (resizable) { [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:YES]; [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; From 5871428c8378eb01b417d97c6611eff1cb92e637 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 14:20:08 +0800 Subject: [PATCH 127/172] spec: BrowserWindow.setResizable should not change window size --- spec/api-browser-window-spec.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 1b5705016831..fa7a8ae33a9c 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -129,6 +129,14 @@ describe 'browser-window module', -> it 'returns the window with id', -> assert.equal w.id, BrowserWindow.fromId(w.id).id + describe 'BrowserWindow.setResizable(resizable)', -> + it 'does not change window size for frameless window', -> + w.destroy() + w = new BrowserWindow(show: true, frame: false) + s = w.getSize() + w.setResizable not w.isResizable() + assert.deepEqual s, w.getSize() + describe '"use-content-size" option', -> it 'make window created with content size when used', -> w.destroy() From 2f04f76e699a65208ef14c273727f7bf1cc4fd7b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 5 Aug 2015 15:49:37 +0800 Subject: [PATCH 128/172] ImageSkiaRep doesn't release memory --- atom/common/api/atom_api_native_image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 7819e314178c..40a73a7de3f7 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -78,7 +78,7 @@ bool AddImageSkiaRep(gfx::ImageSkia* image, if (!decoded) return false; - image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor)); + image->AddRepresentation(gfx::ImageSkiaRep(*decoded, scale_factor)); return true; } From 78eac4116c656b7bb7cb2c539984726068cb7a71 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 5 Aug 2015 13:47:59 +0800 Subject: [PATCH 129/172] Polish thumbar code. * Fix a memory leak in thumbar initialization. * Check the number of thumbar buttons, should be <= 7. * Correct to check thumbar button click event. --- atom/browser/native_window_views.cc | 2 +- .../win/atom_desktop_window_tree_host_win.cc | 8 +++- atom/browser/ui/win/thumbar_host.cc | 43 +++++++++++++------ atom/browser/ui/win/thumbar_host.h | 2 +- docs/api/browser-window.md | 43 ++++++++++--------- filenames.gypi | 4 +- 6 files changed, 64 insertions(+), 38 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 018f294b8df1..eda98dc4f853 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -27,7 +27,6 @@ #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/window/client_view.h" -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/native_widget_private.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/shadow_types.h" @@ -52,6 +51,7 @@ #include "ui/base/win/shell.h" #include "ui/gfx/icon_util.h" #include "ui/gfx/win/dpi.h" +#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/win/hwnd_util.h" #endif diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index 55912612ebba..5c5833f64c09 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -3,6 +3,9 @@ // found in the LICENSE file. #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" + +#include + #include "atom/browser/ui/win/thumbar_host.h" namespace atom { @@ -32,8 +35,11 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG(UINT message, LRESULT* result) { switch (message) { case WM_COMMAND: { + // Handle thumbar button click message. int id = LOWORD(w_param); - if (thumbar_host_ && thumbar_host_->HandleThumbarButtonEvent(id)) + int thbn_message = HIWORD(w_param); + if (thbn_message == THBN_CLICKED && thumbar_host_ && + thumbar_host_->HandleThumbarButtonEvent(id)) return true; } } diff --git a/atom/browser/ui/win/thumbar_host.cc b/atom/browser/ui/win/thumbar_host.cc index 22e9ba8c4169..2d82cd4c6cdb 100644 --- a/atom/browser/ui/win/thumbar_host.cc +++ b/atom/browser/ui/win/thumbar_host.cc @@ -18,9 +18,14 @@ namespace atom { namespace { +// From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ +// dd378460(v=vs.85).aspx#thumbbars // The thumbnail toolbar has a maximum of seven buttons due to the limited room. const int kMaxButtonsCount = 7; +// The base id of Thumbar button. +const int kButtonIdBase = 40001; + bool GetThumbarButtonFlags(const std::vector& flags, THUMBBUTTONFLAGS* out) { if (flags.empty()) { @@ -60,7 +65,18 @@ ThumbarHost::~ThumbarHost() { bool ThumbarHost::SetThumbarButtons( const std::vector& buttons) { - THUMBBUTTON thumb_buttons[kMaxButtonsCount]; + if (buttons.size() > kMaxButtonsCount) + return false; + + base::win::ScopedComPtr taskbar; + if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, + nullptr, + CLSCTX_INPROC_SERVER)) || + FAILED(taskbar->HrInit())) { + return false; + } + + THUMBBUTTON thumb_buttons[kMaxButtonsCount] = {}; thumbar_button_clicked_callback_map_.clear(); // Once a toolbar with a set of buttons is added to thumbnail, there is no way @@ -70,7 +86,8 @@ bool ThumbarHost::SetThumbarButtons( // // Initialize all thumb buttons with HIDDEN state. for (int i = 0; i < kMaxButtonsCount; ++i) { - thumb_buttons[i].iId = i; + thumb_buttons[i].iId = kButtonIdBase + i; + thumb_buttons[i].dwMask = THB_FLAGS; // dwFlags is valid. thumb_buttons[i].dwFlags = THBF_HIDDEN; } @@ -87,25 +104,25 @@ bool ThumbarHost::SetThumbarButtons( base::UTF8ToUTF16(buttons[i].tooltip).c_str()); } - thumbar_button_clicked_callback_map_[i] = + thumbar_button_clicked_callback_map_[thumb_buttons[i].iId] = buttons[i].clicked_callback; } - base::win::ScopedComPtr taskbar; - if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, - nullptr, - CLSCTX_INPROC_SERVER)) || - FAILED(taskbar->HrInit())) { - return false; - } + bool is_success = false; if (!is_initialized_) { is_initialized_ = true; - return taskbar->ThumbBarAddButtons( + is_success = taskbar->ThumbBarAddButtons( + window_, kMaxButtonsCount, thumb_buttons) == S_OK; + } else { + is_success = taskbar->ThumbBarUpdateButtons( window_, kMaxButtonsCount, thumb_buttons) == S_OK; } - return taskbar->ThumbBarUpdateButtons( - window_, kMaxButtonsCount, thumb_buttons) == S_OK; + // Release thumb_buttons' icons, the taskbar makes its own copy. + for (size_t i = 0; i < buttons.size(); ++i) { + ::DestroyIcon(thumb_buttons[i].hIcon); + } + return is_success; } bool ThumbarHost::HandleThumbarButtonEvent(int button_id) { diff --git a/atom/browser/ui/win/thumbar_host.h b/atom/browser/ui/win/thumbar_host.h index 2ab3b06a381d..40d0ae7400e8 100644 --- a/atom/browser/ui/win/thumbar_host.h +++ b/atom/browser/ui/win/thumbar_host.h @@ -18,7 +18,7 @@ namespace atom { class ThumbarHost { public: - using ThumbarButtonClickedCallback = base::Callback; + using ThumbarButtonClickedCallback = base::Closure; struct ThumbarButton { std::string tooltip; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 73f9c97de58d..60b9b84735d0 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -648,29 +648,32 @@ __Note:__ This API is only available on Windows (Windows 7 and above) * `buttons` Array of `button` objects * `button` Object - * `icon` [NativeImage](native-image.md) - The icon showing in thumbnail toolbar. - * `tooltip` String - (Option) - The text of the button's tooltip. - * `flags` Array of Strings - (Option) Control specific states and behaviors - of the button. By default, it uses `enabled`. - * `enabled` - The button is active and available to the user. - * `disabled` - The button is disabled. It is present, but has a visual state - that indicates that it will not respond to user action. - * `dismissonclick` - When the button is clicked, the taskbar button's flyout - closes immediately. - * `nobackground` - Do not draw a button border, use only the image. - * `hidden` - The button is not shown to the user. - * `noninteractive` - The button is enabled but not interactive; no pressed - button state is drawn. This value is intended for instances where the button - is used in a notification. - * `click` - Function + * `icon` [NativeImage](native-image.md) - The icon showing in thumbnail + toolbar. + * `tooltip` String - (Option) - The text of the button's tooltip. + * `flags` Array of Strings - (Option) Control specific states and behaviors + of the button. By default, it uses `enabled`. + * `enabled` - The button is active and available to the user. + * `disabled` - The button is disabled. It is present, but has a visual + state that indicates that it will not respond to user action. + * `dismissonclick` - When the button is clicked, the taskbar button's + flyout closes immediately. + * `nobackground` - Do not draw a button border, use only the image. + * `hidden` - The button is not shown to the user. + * `noninteractive` - The button is enabled but not interactive; no + pressed button state is drawn. This value is intended for instances + where the button is used in a notification. + * `click` - Function -Add a thumbnail toolbar with a specified set of buttons to the thumbnail image of -a window in a taskbar button layout. +Add a thumbnail toolbar with a specified set of buttons to the thumbnail image +of a window in a taskbar button layout. Returns a `Boolean` object indicates +whether the thumbnail has been added successfully. __Note:__ This API is only available on Windows (Windows 7 and above). -Once you setup the thumbnail toolbar, the toolbar cannot be removed due to the -platform's limitation. But you can call the API with an empty array to clean the -buttons. +The number of buttons in thumbnail toolbar should be no greater than 7 due to +the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be +removed due to the platform's limitation. But you can call the API with an empty +array to clean the buttons. ### BrowserWindow.showDefinitionForSelection() diff --git a/filenames.gypi b/filenames.gypi index 3b3d3a4cc48f..45aaac7c2778 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -119,8 +119,6 @@ 'atom/browser/atom_browser_main_parts.h', 'atom/browser/atom_browser_main_parts_linux.cc', 'atom/browser/atom_browser_main_parts_mac.mm', - "atom/browser/atom_desktop_window_tree_host_win.cc", - "atom/browser/atom_desktop_window_tree_host_win.h", 'atom/browser/atom_javascript_dialog_manager.cc', 'atom/browser/atom_javascript_dialog_manager.h', 'atom/browser/atom_quota_permission_context.cc', @@ -204,6 +202,8 @@ 'atom/browser/ui/views/submenu_button.h', 'atom/browser/ui/views/win_frame_view.cc', 'atom/browser/ui/views/win_frame_view.h', + "atom/browser/ui/win/atom_desktop_window_tree_host_win.cc", + "atom/browser/ui/win/atom_desktop_window_tree_host_win.h", 'atom/browser/ui/win/notify_icon_host.cc', 'atom/browser/ui/win/notify_icon_host.h', 'atom/browser/ui/win/notify_icon.cc', From 6b8d4a43a34fc17c03471e8ecf3db4b19336390b Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 5 Aug 2015 13:33:08 +0530 Subject: [PATCH 130/172] override: intialise BrowserWindowProxy.closed --- atom/renderer/lib/override.coffee | 1 + spec/chromium-spec.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index d0f1fabc4ac9..d8c6c0a86d79 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -11,6 +11,7 @@ resolveUrl = (url) -> # Window object returned by "window.open". class BrowserWindowProxy constructor: (@guestId) -> + @closed = false ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (guestId) => if guestId is @guestId @closed = true diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index 375f98966bea..32fd5bed6742 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -37,6 +37,7 @@ describe 'chromium feature', -> describe 'window.open', -> it 'returns a BrowserWindowProxy object', -> b = window.open 'about:blank', 'test', 'show=no' + assert.equal b.closed, false assert.equal b.constructor.name, 'BrowserWindowProxy' b.close() From 0a7a4c0d0a58bdc6cc3a060fb3a807c2fccd5686 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 5 Aug 2015 17:20:23 +0530 Subject: [PATCH 131/172] webview: adding load-commit event --- atom/browser/lib/guest-view-manager.coffee | 1 + atom/browser/web_view_guest_delegate.cc | 8 ++++++++ atom/browser/web_view_guest_delegate.h | 3 +++ atom/renderer/lib/web-view/guest-view-internal.coffee | 2 ++ atom/renderer/lib/web-view/web-view-attributes.coffee | 2 +- atom/renderer/lib/web-view/web-view.coffee | 6 +++--- docs/api/web-view-tag.md | 9 +++++++++ 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 4385d389c39d..971c15cb1b85 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -3,6 +3,7 @@ webContents = require 'web-contents' webViewManager = null # Doesn't exist in early initialization. supportedWebViewEvents = [ + 'load-commit' 'did-finish-load' 'did-fail-load' 'did-frame-finish-load' diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 98fa72da22d4..38f4da4c1f96 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -5,7 +5,9 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/browser/api/atom_api_web_contents.h" +#include "atom/common/native_mate_converters/gurl_converter.h" #include "content/public/browser/guest_host.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" @@ -128,6 +130,12 @@ void WebViewGuestDelegate::RenderViewReady() { render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT); } +void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, ui::PageTransition transition_type) { + api_web_contents_->Emit("load-commit", url, !render_frame_host->GetParent()); +} + void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) { api_web_contents_->Emit("did-attach"); } diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index 267b5b248af6..3312b46104a0 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -59,6 +59,9 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, protected: // content::WebContentsObserver: void RenderViewReady() override; + void DidCommitProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, ui::PageTransition transition_type) override; // content::BrowserPluginGuestDelegate: void DidAttach(int guest_proxy_routing_id) final; diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index b62418d146d9..44db5e304db4 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -4,6 +4,7 @@ webFrame = require 'web-frame' requestId = 0 WEB_VIEW_EVENTS = + 'load-commit': ['url', 'isMainFrame'] 'did-finish-load': [] 'did-fail-load': ['errorCode', 'errorDescription'] 'did-frame-finish-load': ['isMainFrame'] @@ -32,6 +33,7 @@ dispatchEvent = (webView, event, args...) -> for f, i in WEB_VIEW_EVENTS[event] domEvent[f] = args[i] webView.dispatchEvent domEvent + webView.onLoadCommit domEvent if event == 'load-commit' module.exports = registerEvents: (webView, viewInstanceId) -> diff --git a/atom/renderer/lib/web-view/web-view-attributes.coffee b/atom/renderer/lib/web-view/web-view-attributes.coffee index 82229aae57b1..acca826a9e3d 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.coffee +++ b/atom/renderer/lib/web-view/web-view-attributes.coffee @@ -120,7 +120,7 @@ class SrcAttribute extends WebViewAttribute '' setValueIgnoreMutation: (value) -> - WebViewAttribute::setValueIgnoreMutation value + WebViewAttribute::setValueIgnoreMutation.call(this, value) # takeRecords() is needed to clear queued up src mutations. Without it, it # is possible for this change to get picked up asyncronously by src's # mutation observer |observer|, and then get handled even though we do not diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index eedee732938f..35fbe17796f4 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -157,10 +157,10 @@ class WebViewImpl enumerable: true # Updates state upon loadcommit. - onLoadCommit: (@baseUrlForDataUrl, @currentEntryIndex, @entryCount, @processId, url, isTopLevel) -> + onLoadCommit: (webViewEvent) -> oldValue = @webviewNode.getAttribute webViewConstants.ATTRIBUTE_SRC - newValue = url - if isTopLevel and (oldValue != newValue) + newValue = webViewEvent.url + if webViewEvent.isMainFrame and (oldValue != newValue) # Touching the src attribute triggers a navigation. To avoid # triggering a page reload on every guest-initiated navigation, # we do not handle this mutation diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index a74f5fb50c77..07d84324dd4b 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -335,6 +335,15 @@ examples. ## DOM events +### load-commit + +* `url` String +* `isMainFrame` Boolean + +Fired when a load has committed. This includes navigation within the current +document as well as subframe document-level loads, but does not include +asynchronous resource loads. + ### did-finish-load Fired when the navigation is done, i.e. the spinner of the tab will stop From 2f1cb8b52a195655f85be428a953c41c0644b039 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 5 Aug 2015 22:26:18 +0800 Subject: [PATCH 132/172] Expose NativeWindow.setThumbarButtons API to all platforms. --- atom/browser/api/atom_api_window.cc | 16 +++------------- atom/browser/api/atom_api_window.h | 9 ++------- atom/browser/native_window.cc | 5 +++++ atom/browser/native_window.h | 18 ++++++++++-------- atom/browser/native_window_views.cc | 6 +++--- atom/browser/native_window_views.h | 4 +--- .../win/atom_desktop_window_tree_host_win.cc | 3 ++- .../ui/win/atom_desktop_window_tree_host_win.h | 3 ++- atom/browser/ui/win/thumbar_host.cc | 6 ++++-- atom/browser/ui/win/thumbar_host.h | 17 +++-------------- 10 files changed, 35 insertions(+), 52 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bcdc57c3c704..0b2c8c9ece79 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -20,17 +20,12 @@ #include "atom/common/node_includes.h" -#if defined(OS_WIN) -#include "atom/browser/ui/win/thumbar_host.h" -#endif - namespace mate { -#if defined(OS_WIN) template<> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, - atom::ThumbarHost::ThumbarButton* out) { + atom::NativeWindow::ThumbarButton* out) { mate::Dictionary dict; if (!ConvertFromV8(isolate, val, &dict)) return false; @@ -40,7 +35,6 @@ struct Converter { return dict.Get("icon", &(out->icon)); } }; -#endif } // namespace mate @@ -437,12 +431,10 @@ void Window::SetOverlayIcon(const gfx::Image& overlay, window_->SetOverlayIcon(overlay, description); } -#if defined(OS_WIN) void Window::SetThumbarButtons( - const std::vector& buttons) { + const std::vector& buttons) { window_->SetThumbarButtons(buttons); } -#endif void Window::SetMenu(v8::Isolate* isolate, v8::Local value) { mate::Handle menu; @@ -569,9 +561,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("capturePage", &Window::CapturePage) .SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon) -#if defined(OS_WIN) .SetMethod("setThumbarButtons", &Window::SetThumbarButtons) -#endif .SetMethod("setMenu", &Window::SetMenu) .SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar) .SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index fdb10825a6ca..7742c8a9fa9b 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -11,13 +11,10 @@ #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 "native_mate/handle.h" -#if defined(OS_WIN) -#include "atom/browser/ui/win/thumbar_host.h" -#endif - class GURL; namespace gfx { @@ -133,10 +130,8 @@ class Window : public mate::TrackableObject, void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); -#if defined(OS_WIN) void SetThumbarButtons( - const std::vector& buttons); -#endif + const std::vector& buttons); void SetMenu(v8::Isolate* isolate, v8::Local menu); void SetAutoHideMenuBar(bool auto_hide); bool IsMenuBarAutoHide(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 96085846bca8..91770af316e3 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -277,6 +277,11 @@ bool NativeWindow::HasModalDialog() { return has_dialog_attached_; } +bool NativeWindow::SetThumbarButtons( + const std::vector& buttons) { + return false; +} + void NativeWindow::FocusOnWebView() { web_contents()->GetRenderViewHost()->Focus(); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ae22214f563..d461215222d6 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -23,10 +23,6 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" -#if defined(OS_WIN) -#include "atom/browser/ui/win/thumbar_host.h" -#endif - class SkRegion; namespace base { @@ -63,7 +59,15 @@ struct DraggableRegion; class NativeWindow : public content::WebContentsObserver, public brightray::InspectableWebContentsViewDelegate { public: - typedef base::Callback CapturePageCallback; + using CapturePageCallback = base::Callback; + using ThumbarButtonClickedCallback = base::Closure; + + struct ThumbarButton { + std::string tooltip; + gfx::Image icon; + std::vector flags; + ThumbarButtonClickedCallback clicked_callback; + }; class DialogScope { public: @@ -148,10 +152,8 @@ class NativeWindow : public content::WebContentsObserver, const std::string& description) = 0; virtual void SetVisibleOnAllWorkspaces(bool visible) = 0; virtual bool IsVisibleOnAllWorkspaces() = 0; -#if defined(OS_WIN) virtual bool SetThumbarButtons( - const std::vector& buttons) = 0; -#endif + const std::vector& buttons); virtual bool IsClosed() const { return is_closed_; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index eda98dc4f853..acb7de33f4d6 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -717,17 +717,17 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() { return false; } -#if defined(OS_WIN) bool NativeWindowViews::SetThumbarButtons( - const std::vector& buttons) { + const std::vector& buttons) { +#if defined(OS_WIN) if (atom_desktop_window_tree_host_win_) { return atom_desktop_window_tree_host_win_->SetThumbarButtons( views::HWNDForNativeWindow(window_->GetNativeWindow()), buttons); } +#endif return false; } -#endif gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() { return GetNativeWindow()->GetHost()->GetAcceleratedWidget(); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 94c0c04373f7..792a72c75624 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -82,10 +82,8 @@ class NativeWindowViews : public NativeWindow, bool IsMenuBarVisible() override; void SetVisibleOnAllWorkspaces(bool visible) override; bool IsVisibleOnAllWorkspaces() override; -#if defined(OS_WIN) bool SetThumbarButtons( - const std::vector& buttons) override; -#endif + const std::vector& buttons) override; gfx::AcceleratedWidget GetAcceleratedWidget(); diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index 5c5833f64c09..157cb610fb3a 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -6,6 +6,7 @@ #include +#include "atom/browser/native_window.h" #include "atom/browser/ui/win/thumbar_host.h" namespace atom { @@ -22,7 +23,7 @@ AtomDesktopWindowTreeHostWin::~AtomDesktopWindowTreeHostWin() { bool AtomDesktopWindowTreeHostWin::SetThumbarButtons( HWND window, - const std::vector& buttons) { + const std::vector& buttons) { if (!thumbar_host_.get()) { thumbar_host_.reset(new ThumbarHost(window)); } diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h index 7f2abf801ad3..fc09b6503b80 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h @@ -9,6 +9,7 @@ #include +#include "atom/browser/native_window.h" #include "atom/browser/ui/win/thumbar_host.h" #include "base/memory/scoped_ptr.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" @@ -24,7 +25,7 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { bool SetThumbarButtons( HWND window, - const std::vector& buttons); + const std::vector& buttons); protected: bool PreHandleMSG(UINT message, diff --git a/atom/browser/ui/win/thumbar_host.cc b/atom/browser/ui/win/thumbar_host.cc index 2d82cd4c6cdb..af57ef4e5c64 100644 --- a/atom/browser/ui/win/thumbar_host.cc +++ b/atom/browser/ui/win/thumbar_host.cc @@ -6,6 +6,8 @@ #include +#include + #include "base/win/scoped_comptr.h" #include "base/win/win_util.h" #include "base/win/wrapped_window_proc.h" @@ -64,7 +66,7 @@ ThumbarHost::~ThumbarHost() { } bool ThumbarHost::SetThumbarButtons( - const std::vector& buttons) { + const std::vector& buttons) { if (buttons.size() > kMaxButtonsCount) return false; @@ -112,7 +114,7 @@ bool ThumbarHost::SetThumbarButtons( if (!is_initialized_) { is_initialized_ = true; is_success = taskbar->ThumbBarAddButtons( - window_, kMaxButtonsCount, thumb_buttons) == S_OK; + window_, buttons.size(), thumb_buttons) == S_OK; } else { is_success = taskbar->ThumbBarUpdateButtons( window_, kMaxButtonsCount, thumb_buttons) == S_OK; diff --git a/atom/browser/ui/win/thumbar_host.h b/atom/browser/ui/win/thumbar_host.h index 40d0ae7400e8..d14bbaeda305 100644 --- a/atom/browser/ui/win/thumbar_host.h +++ b/atom/browser/ui/win/thumbar_host.h @@ -8,35 +8,24 @@ #include #include -#include #include -#include "base/callback.h" -#include "ui/gfx/image/image.h" +#include "atom/browser/native_window.h" namespace atom { class ThumbarHost { public: - using ThumbarButtonClickedCallback = base::Closure; - - struct ThumbarButton { - std::string tooltip; - gfx::Image icon; - std::vector flags; - ThumbarButtonClickedCallback clicked_callback; - }; - explicit ThumbarHost(HWND window); ~ThumbarHost(); bool SetThumbarButtons( - const std::vector& buttons); + const std::vector& buttons); bool HandleThumbarButtonEvent(int button_id); private: using ThumbarButtonClickedCallbackMap = std::map< - int, ThumbarButtonClickedCallback>; + int, NativeWindow::ThumbarButtonClickedCallback>; ThumbarButtonClickedCallbackMap thumbar_button_clicked_callback_map_; bool is_initialized_; From d175a685864371ae28e5fd4d803570b9c144777c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 10:15:27 +0800 Subject: [PATCH 133/172] Add MessageHandlerDelegate --- atom/browser/native_window_views.cc | 4 +-- atom/browser/native_window_views.h | 7 +++++ .../win/atom_desktop_window_tree_host_win.cc | 4 ++- .../win/atom_desktop_window_tree_host_win.h | 15 +++++++---- .../ui/win/message_handler_delegate.cc | 14 ++++++++++ .../browser/ui/win/message_handler_delegate.h | 26 +++++++++++++++++++ filenames.gypi | 6 +++-- 7 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 atom/browser/ui/win/message_handler_delegate.cc create mode 100644 atom/browser/ui/win/message_handler_delegate.h diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index acb7de33f4d6..a4fdfc7993b6 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -221,11 +221,11 @@ NativeWindowViews::NativeWindowViews( params.native_widget = new views::DesktopNativeWidgetAura(window_.get()); atom_desktop_window_tree_host_win_ = new AtomDesktopWindowTreeHostWin( + this, window_.get(), static_cast(params.native_widget)); params.desktop_window_tree_host = atom_desktop_window_tree_host_win_; -#endif -#if defined(USE_X11) +#elif defined(USE_X11) std::string name = Browser::Get()->GetName(); // Set WM_WINDOW_ROLE. params.wm_role_name = "browser-window"; diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 792a72c75624..3adfa4cd0dc1 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -14,6 +14,10 @@ #include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_observer.h" +#if defined(OS_WIN) +#include "atom/browser/ui/win/message_handler_delegate.h" +#endif + namespace views { class UnhandledKeyboardEventHandler; } @@ -28,6 +32,9 @@ class AtomDesktopWindowTreeHostWin; #endif class NativeWindowViews : public NativeWindow, +#if defined(OS_WIN) + public MessageHandlerDelegate, +#endif public views::WidgetDelegateView, public views::WidgetObserver { public: diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index 157cb610fb3a..f291e66d794e 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -12,10 +12,12 @@ namespace atom { AtomDesktopWindowTreeHostWin::AtomDesktopWindowTreeHostWin( + MessageHandlerDelegate* delegate, views::internal::NativeWidgetDelegate* native_widget_delegate, views::DesktopNativeWidgetAura* desktop_native_widget_aura) : views::DesktopWindowTreeHostWin(native_widget_delegate, - desktop_native_widget_aura) { + desktop_native_widget_aura), + delegate_(delegate) { } AtomDesktopWindowTreeHostWin::~AtomDesktopWindowTreeHostWin() { diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h index fc09b6503b80..7681ef6a95d8 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h @@ -16,25 +16,30 @@ namespace atom { +class MessageHandlerDelegate; + class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { public: AtomDesktopWindowTreeHostWin( + MessageHandlerDelegate* delegate, views::internal::NativeWidgetDelegate* native_widget_delegate, views::DesktopNativeWidgetAura* desktop_native_widget_aura); - ~AtomDesktopWindowTreeHostWin(); + ~AtomDesktopWindowTreeHostWin() override; bool SetThumbarButtons( HWND window, const std::vector& buttons); protected: - bool PreHandleMSG(UINT message, - WPARAM w_param, - LPARAM l_param, - LRESULT* result) override; + bool PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; private: + MessageHandlerDelegate* delegate_; // weak ref + scoped_ptr thumbar_host_; + + DISALLOW_COPY_AND_ASSIGN(AtomDesktopWindowTreeHostWin); }; } // namespace atom diff --git a/atom/browser/ui/win/message_handler_delegate.cc b/atom/browser/ui/win/message_handler_delegate.cc new file mode 100644 index 000000000000..791d1fd816d9 --- /dev/null +++ b/atom/browser/ui/win/message_handler_delegate.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/win/message_handler_delegate.h" + +namespace atom { + +bool MessageHandlerDelegate::PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { + return false; +} + +} // namespace atom diff --git a/atom/browser/ui/win/message_handler_delegate.h b/atom/browser/ui/win/message_handler_delegate.h new file mode 100644 index 000000000000..d8cfcf7fc43b --- /dev/null +++ b/atom/browser/ui/win/message_handler_delegate.h @@ -0,0 +1,26 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_ +#define ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_ + +#include + +namespace atom { + +class MessageHandlerDelegate { + public: + // Catch-all message handling and filtering. Called before + // HWNDMessageHandler's built-in handling, which may pre-empt some + // expectations in Views/Aura if messages are consumed. Returns true if the + // message was consumed by the delegate and should not be processed further + // by the HWNDMessageHandler. In this case, |result| is returned. |result| is + // not modified otherwise. + virtual bool PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_WIN_MESSAGE_HANDLER_DELEGATE_H_ diff --git a/filenames.gypi b/filenames.gypi index 45aaac7c2778..40832b74f6a3 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -202,8 +202,10 @@ 'atom/browser/ui/views/submenu_button.h', 'atom/browser/ui/views/win_frame_view.cc', 'atom/browser/ui/views/win_frame_view.h', - "atom/browser/ui/win/atom_desktop_window_tree_host_win.cc", - "atom/browser/ui/win/atom_desktop_window_tree_host_win.h", + 'atom/browser/ui/win/atom_desktop_window_tree_host_win.cc', + 'atom/browser/ui/win/atom_desktop_window_tree_host_win.h', + 'atom/browser/ui/win/message_handler_delegate.cc', + 'atom/browser/ui/win/message_handler_delegate.h', 'atom/browser/ui/win/notify_icon_host.cc', 'atom/browser/ui/win/notify_icon_host.h', 'atom/browser/ui/win/notify_icon.cc', From 39af10cc8d59baa198daf05b4004d8a1a25fe6c8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 10:25:50 +0800 Subject: [PATCH 134/172] Move thumbar_host_ from TreeHost to NativeWindow --- atom/browser/native_window_views.cc | 24 ++++++++++---- atom/browser/native_window_views.h | 10 ++++++ .../win/atom_desktop_window_tree_host_win.cc | 33 +++---------------- .../win/atom_desktop_window_tree_host_win.h | 8 ----- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index a4fdfc7993b6..09e10608d271 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -46,6 +46,7 @@ #elif defined(OS_WIN) #include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" +#include "atom/browser/ui/win/thumbar_host.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "ui/base/win/shell.h" @@ -720,13 +721,12 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() { bool NativeWindowViews::SetThumbarButtons( const std::vector& buttons) { #if defined(OS_WIN) - if (atom_desktop_window_tree_host_win_) { - return atom_desktop_window_tree_host_win_->SetThumbarButtons( - views::HWNDForNativeWindow(window_->GetNativeWindow()), - buttons); - } -#endif + if (!thumbar_host_) + thumbar_host_.reset(new ThumbarHost(GetAcceleratedWidget())); + return thumbar_host_->SetThumbarButtons(buttons); +#else return false; +#endif } gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() { @@ -890,6 +890,18 @@ void NativeWindowViews::GetDevToolsWindowWMClass( } #endif +#if defined(OS_WIN) +bool NativeWindowViews::PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { + // Handle thumbar button click message. + if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED && + thumbar_host_) + return thumbar_host_->HandleThumbarButtonEvent(LOWORD(w_param)); + else + return false; +} +#endif + void NativeWindowViews::HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 3adfa4cd0dc1..647467548d9d 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -27,8 +27,10 @@ namespace atom { class GlobalMenuBarX11; class MenuBar; class WindowStateWatcher; + #if defined(OS_WIN) class AtomDesktopWindowTreeHostWin; +class ThumbarHost; #endif class NativeWindowViews : public NativeWindow, @@ -134,6 +136,12 @@ class NativeWindowViews : public NativeWindow, std::string* name, std::string* class_name) override; #endif +#if defined(OS_WIN) + // MessageHandlerDelegate: + bool PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; +#endif + // NativeWindow: void HandleKeyboardEvent( content::WebContents*, @@ -171,6 +179,8 @@ class NativeWindowViews : public NativeWindow, // Records window was whether restored from minimized state or maximized // state. bool is_minimized_; + // In charge of running thumbar related APIs. + scoped_ptr thumbar_host_; #endif // Handles unhandled keyboard messages coming back from the renderer process. diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index f291e66d794e..84a6d9aa3e50 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -4,10 +4,7 @@ #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" -#include - -#include "atom/browser/native_window.h" -#include "atom/browser/ui/win/thumbar_host.h" +#include "atom/browser/ui/win/message_handler_delegate.h" namespace atom { @@ -23,31 +20,9 @@ AtomDesktopWindowTreeHostWin::AtomDesktopWindowTreeHostWin( AtomDesktopWindowTreeHostWin::~AtomDesktopWindowTreeHostWin() { } -bool AtomDesktopWindowTreeHostWin::SetThumbarButtons( - HWND window, - const std::vector& buttons) { - if (!thumbar_host_.get()) { - thumbar_host_.reset(new ThumbarHost(window)); - } - return thumbar_host_->SetThumbarButtons(buttons); -} - -bool AtomDesktopWindowTreeHostWin::PreHandleMSG(UINT message, - WPARAM w_param, - LPARAM l_param, - LRESULT* result) { - switch (message) { - case WM_COMMAND: { - // Handle thumbar button click message. - int id = LOWORD(w_param); - int thbn_message = HIWORD(w_param); - if (thbn_message == THBN_CLICKED && thumbar_host_ && - thumbar_host_->HandleThumbarButtonEvent(id)) - return true; - } - } - - return false; +bool AtomDesktopWindowTreeHostWin::PreHandleMSG( + UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { + return delegate_->PreHandleMSG(message, w_param, l_param, result); } } // namespace atom diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h index 7681ef6a95d8..47e4cb6aed2a 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h @@ -10,8 +10,6 @@ #include #include "atom/browser/native_window.h" -#include "atom/browser/ui/win/thumbar_host.h" -#include "base/memory/scoped_ptr.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" namespace atom { @@ -26,10 +24,6 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { views::DesktopNativeWidgetAura* desktop_native_widget_aura); ~AtomDesktopWindowTreeHostWin() override; - bool SetThumbarButtons( - HWND window, - const std::vector& buttons); - protected: bool PreHandleMSG( UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; @@ -37,8 +31,6 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { private: MessageHandlerDelegate* delegate_; // weak ref - scoped_ptr thumbar_host_; - DISALLOW_COPY_AND_ASSIGN(AtomDesktopWindowTreeHostWin); }; From 8f8c3aef878f54698b847bd0d4a551a686582539 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 10:30:22 +0800 Subject: [PATCH 135/172] ThumbarHost => TaskbarHost --- atom/browser/native_window_views.cc | 12 ++++++------ atom/browser/native_window_views.h | 6 +++--- .../ui/win/{thumbar_host.cc => taskbar_host.cc} | 10 +++++----- .../ui/win/{thumbar_host.h => taskbar_host.h} | 14 +++++++------- filenames.gypi | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) rename atom/browser/ui/win/{thumbar_host.cc => taskbar_host.cc} (94%) rename atom/browser/ui/win/{thumbar_host.h => taskbar_host.h} (72%) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 09e10608d271..c7fd0b8b3524 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -46,7 +46,7 @@ #elif defined(OS_WIN) #include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" -#include "atom/browser/ui/win/thumbar_host.h" +#include "atom/browser/ui/win/taskbar_host.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "ui/base/win/shell.h" @@ -721,9 +721,9 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() { bool NativeWindowViews::SetThumbarButtons( const std::vector& buttons) { #if defined(OS_WIN) - if (!thumbar_host_) - thumbar_host_.reset(new ThumbarHost(GetAcceleratedWidget())); - return thumbar_host_->SetThumbarButtons(buttons); + if (!taskbar_host_) + taskbar_host_.reset(new TaskbarHost(GetAcceleratedWidget())); + return taskbar_host_->SetThumbarButtons(buttons); #else return false; #endif @@ -895,8 +895,8 @@ bool NativeWindowViews::PreHandleMSG( UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { // Handle thumbar button click message. if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED && - thumbar_host_) - return thumbar_host_->HandleThumbarButtonEvent(LOWORD(w_param)); + taskbar_host_) + return taskbar_host_->HandleThumbarButtonEvent(LOWORD(w_param)); else return false; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 647467548d9d..0cc79facab12 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -30,7 +30,7 @@ class WindowStateWatcher; #if defined(OS_WIN) class AtomDesktopWindowTreeHostWin; -class ThumbarHost; +class TaskbarHost; #endif class NativeWindowViews : public NativeWindow, @@ -179,8 +179,8 @@ class NativeWindowViews : public NativeWindow, // Records window was whether restored from minimized state or maximized // state. bool is_minimized_; - // In charge of running thumbar related APIs. - scoped_ptr thumbar_host_; + // In charge of running taskbar related APIs. + scoped_ptr taskbar_host_; #endif // Handles unhandled keyboard messages coming back from the renderer process. diff --git a/atom/browser/ui/win/thumbar_host.cc b/atom/browser/ui/win/taskbar_host.cc similarity index 94% rename from atom/browser/ui/win/thumbar_host.cc rename to atom/browser/ui/win/taskbar_host.cc index af57ef4e5c64..6f74a7d9cb37 100644 --- a/atom/browser/ui/win/thumbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "atom/browser/ui/win/thumbar_host.h" +#include "atom/browser/ui/win/taskbar_host.h" #include @@ -58,14 +58,14 @@ bool GetThumbarButtonFlags(const std::vector& flags, } // namespace -ThumbarHost::ThumbarHost(HWND window) : is_initialized_(false), +TaskbarHost::TaskbarHost(HWND window) : is_initialized_(false), window_(window) { } -ThumbarHost::~ThumbarHost() { +TaskbarHost::~TaskbarHost() { } -bool ThumbarHost::SetThumbarButtons( +bool TaskbarHost::SetThumbarButtons( const std::vector& buttons) { if (buttons.size() > kMaxButtonsCount) return false; @@ -127,7 +127,7 @@ bool ThumbarHost::SetThumbarButtons( return is_success; } -bool ThumbarHost::HandleThumbarButtonEvent(int button_id) { +bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { if (thumbar_button_clicked_callback_map_.find(button_id) != thumbar_button_clicked_callback_map_.end()) { auto callback = thumbar_button_clicked_callback_map_[button_id]; diff --git a/atom/browser/ui/win/thumbar_host.h b/atom/browser/ui/win/taskbar_host.h similarity index 72% rename from atom/browser/ui/win/thumbar_host.h rename to atom/browser/ui/win/taskbar_host.h index d14bbaeda305..e0a9dc89ff4b 100644 --- a/atom/browser/ui/win/thumbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ -#define ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ +#ifndef ATOM_BROWSER_UI_WIN_TASKBAR_HOST_H_ +#define ATOM_BROWSER_UI_WIN_TASKBAR_HOST_H_ #include @@ -14,10 +14,10 @@ namespace atom { -class ThumbarHost { +class TaskbarHost { public: - explicit ThumbarHost(HWND window); - ~ThumbarHost(); + explicit TaskbarHost(HWND window); + ~TaskbarHost(); bool SetThumbarButtons( const std::vector& buttons); @@ -32,9 +32,9 @@ class ThumbarHost { HWND window_; - DISALLOW_COPY_AND_ASSIGN(ThumbarHost); + DISALLOW_COPY_AND_ASSIGN(TaskbarHost); }; } // namespace atom -#endif // ATOM_BROWSER_UI_WIN_THUMBAR_HOST_H_ +#endif // ATOM_BROWSER_UI_WIN_TASKBAR_HOST_H_ diff --git a/filenames.gypi b/filenames.gypi index 40832b74f6a3..f7b9fca5e717 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -210,8 +210,8 @@ 'atom/browser/ui/win/notify_icon_host.h', 'atom/browser/ui/win/notify_icon.cc', 'atom/browser/ui/win/notify_icon.h', - 'atom/browser/ui/win/thumbar_host.cc', - 'atom/browser/ui/win/thumbar_host.h', + 'atom/browser/ui/win/taskbar_host.cc', + 'atom/browser/ui/win/taskbar_host.h', 'atom/browser/ui/x/window_state_watcher.cc', 'atom/browser/ui/x/window_state_watcher.h', 'atom/browser/ui/x/x_window_utils.cc', From a28f70e85ca232ae084f3e8ac5cf9420a6d4ff93 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 11:10:34 +0800 Subject: [PATCH 136/172] Decouple TaskbarHost from NativeWindow --- atom/browser/api/atom_api_window.cc | 25 ++++++++++++++++++++----- atom/browser/api/atom_api_window.h | 3 +-- atom/browser/native_window.cc | 5 ----- atom/browser/native_window.h | 18 ++++++------------ atom/browser/native_window_views.cc | 17 ++--------------- atom/browser/native_window_views.h | 10 ++++++---- atom/browser/ui/win/taskbar_host.cc | 9 ++++----- atom/browser/ui/win/taskbar_host.h | 21 +++++++++++++-------- 8 files changed, 52 insertions(+), 56 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 0b2c8c9ece79..2cbe8be566e2 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -18,14 +18,20 @@ #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" +#if defined(OS_WIN) +#include "atom/browser/native_window_views.h" +#include "atom/browser/ui/win/taskbar_host.h" +#endif + #include "atom/common/node_includes.h" +#if defined(OS_WIN) namespace mate { template<> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, - atom::NativeWindow::ThumbarButton* out) { + atom::TaskbarHost::ThumbarButton* out) { mate::Dictionary dict; if (!ConvertFromV8(isolate, val, &dict)) return false; @@ -37,6 +43,7 @@ struct Converter { }; } // namespace mate +#endif namespace atom { @@ -431,9 +438,17 @@ void Window::SetOverlayIcon(const gfx::Image& overlay, window_->SetOverlayIcon(overlay, description); } -void Window::SetThumbarButtons( - const std::vector& buttons) { - window_->SetThumbarButtons(buttons); +void Window::SetThumbarButtons(mate::Arguments* args) { +#if defined(OS_WIN) + std::vector buttons; + if (!args->GetNext(&buttons)) { + args->ThrowError(); + return; + } + auto window = static_cast(window_.get()); + window->taskbar_host().SetThumbarButtons(window->GetAcceleratedWidget(), + buttons); +#endif } void Window::SetMenu(v8::Isolate* isolate, v8::Local value) { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 7742c8a9fa9b..389c03ab9d40 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -130,8 +130,7 @@ class Window : public mate::TrackableObject, void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); - void SetThumbarButtons( - const std::vector& buttons); + void SetThumbarButtons(mate::Arguments* args); void SetMenu(v8::Isolate* isolate, v8::Local menu); void SetAutoHideMenuBar(bool auto_hide); bool IsMenuBarAutoHide(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 91770af316e3..96085846bca8 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -277,11 +277,6 @@ bool NativeWindow::HasModalDialog() { return has_dialog_attached_; } -bool NativeWindow::SetThumbarButtons( - const std::vector& buttons) { - return false; -} - void NativeWindow::FocusOnWebView() { web_contents()->GetRenderViewHost()->Focus(); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d461215222d6..b9294d38c931 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -60,14 +60,6 @@ class NativeWindow : public content::WebContentsObserver, public brightray::InspectableWebContentsViewDelegate { public: using CapturePageCallback = base::Callback; - using ThumbarButtonClickedCallback = base::Closure; - - struct ThumbarButton { - std::string tooltip; - gfx::Image icon; - std::vector flags; - ThumbarButtonClickedCallback clicked_callback; - }; class DialogScope { public: @@ -103,6 +95,7 @@ class NativeWindow : public content::WebContentsObserver, virtual void Close() = 0; virtual void CloseImmediately() = 0; + virtual bool IsClosed() const { return is_closed_; } virtual void Focus(bool focus) = 0; virtual bool IsFocused() = 0; virtual void Show() = 0; @@ -147,16 +140,17 @@ class NativeWindow : public content::WebContentsObserver, virtual void SetMenu(ui::MenuModel* menu); virtual bool HasModalDialog(); virtual gfx::NativeWindow GetNativeWindow() = 0; + + // Taskbar/Dock APIs. virtual void SetProgressBar(double progress) = 0; virtual void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) = 0; + + // Workspace APIs. virtual void SetVisibleOnAllWorkspaces(bool visible) = 0; virtual bool IsVisibleOnAllWorkspaces() = 0; - virtual bool SetThumbarButtons( - const std::vector& buttons); - - virtual bool IsClosed() const { return is_closed_; } + // Webview APIs. virtual void FocusOnWebView(); virtual void BlurWebView(); virtual bool IsWebViewFocused(); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index c7fd0b8b3524..759249e5aa4e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -46,7 +46,6 @@ #elif defined(OS_WIN) #include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" -#include "atom/browser/ui/win/taskbar_host.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "ui/base/win/shell.h" @@ -718,17 +717,6 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() { return false; } -bool NativeWindowViews::SetThumbarButtons( - const std::vector& buttons) { -#if defined(OS_WIN) - if (!taskbar_host_) - taskbar_host_.reset(new TaskbarHost(GetAcceleratedWidget())); - return taskbar_host_->SetThumbarButtons(buttons); -#else - return false; -#endif -} - gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() { return GetNativeWindow()->GetHost()->GetAcceleratedWidget(); } @@ -894,9 +882,8 @@ void NativeWindowViews::GetDevToolsWindowWMClass( bool NativeWindowViews::PreHandleMSG( UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { // Handle thumbar button click message. - if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED && - taskbar_host_) - return taskbar_host_->HandleThumbarButtonEvent(LOWORD(w_param)); + if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED) + return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param)); else return false; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 0cc79facab12..355f5bd38ef3 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -16,6 +16,7 @@ #if defined(OS_WIN) #include "atom/browser/ui/win/message_handler_delegate.h" +#include "atom/browser/ui/win/taskbar_host.h" #endif namespace views { @@ -30,7 +31,6 @@ class WindowStateWatcher; #if defined(OS_WIN) class AtomDesktopWindowTreeHostWin; -class TaskbarHost; #endif class NativeWindowViews : public NativeWindow, @@ -91,13 +91,15 @@ class NativeWindowViews : public NativeWindow, bool IsMenuBarVisible() override; void SetVisibleOnAllWorkspaces(bool visible) override; bool IsVisibleOnAllWorkspaces() override; - bool SetThumbarButtons( - const std::vector& buttons) override; gfx::AcceleratedWidget GetAcceleratedWidget(); views::Widget* widget() const { return window_.get(); } +#if defined(OS_WIN) + TaskbarHost& taskbar_host() { return taskbar_host_; } +#endif + private: // views::WidgetObserver: void OnWidgetActivationChanged( @@ -180,7 +182,7 @@ class NativeWindowViews : public NativeWindow, // state. bool is_minimized_; // In charge of running taskbar related APIs. - scoped_ptr taskbar_host_; + TaskbarHost taskbar_host_; #endif // Handles unhandled keyboard messages coming back from the renderer process. diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index 6f74a7d9cb37..3173215a4f6b 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -58,15 +58,14 @@ bool GetThumbarButtonFlags(const std::vector& flags, } // namespace -TaskbarHost::TaskbarHost(HWND window) : is_initialized_(false), - window_(window) { +TaskbarHost::TaskbarHost() : is_initialized_(false) { } TaskbarHost::~TaskbarHost() { } bool TaskbarHost::SetThumbarButtons( - const std::vector& buttons) { + HWND window, const std::vector& buttons) { if (buttons.size() > kMaxButtonsCount) return false; @@ -114,10 +113,10 @@ bool TaskbarHost::SetThumbarButtons( if (!is_initialized_) { is_initialized_ = true; is_success = taskbar->ThumbBarAddButtons( - window_, buttons.size(), thumb_buttons) == S_OK; + window, buttons.size(), thumb_buttons) == S_OK; } else { is_success = taskbar->ThumbBarUpdateButtons( - window_, kMaxButtonsCount, thumb_buttons) == S_OK; + window, kMaxButtonsCount, thumb_buttons) == S_OK; } // Release thumb_buttons' icons, the taskbar makes its own copy. diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index e0a9dc89ff4b..2c81a9cdb371 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -10,28 +10,33 @@ #include #include -#include "atom/browser/native_window.h" +#include "base/callback.h" +#include "ui/gfx/image/image.h" namespace atom { class TaskbarHost { public: - explicit TaskbarHost(HWND window); - ~TaskbarHost(); + struct ThumbarButton { + std::string tooltip; + gfx::Image icon; + std::vector flags; + base::Closure clicked_callback; + }; + + TaskbarHost(); + virtual ~TaskbarHost(); bool SetThumbarButtons( - const std::vector& buttons); + HWND window, const std::vector& buttons); bool HandleThumbarButtonEvent(int button_id); private: - using ThumbarButtonClickedCallbackMap = std::map< - int, NativeWindow::ThumbarButtonClickedCallback>; + using ThumbarButtonClickedCallbackMap = std::map; ThumbarButtonClickedCallbackMap thumbar_button_clicked_callback_map_; bool is_initialized_; - HWND window_; - DISALLOW_COPY_AND_ASSIGN(TaskbarHost); }; From 958658513c0b33aa90694ec2797c995526e5555a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 12:44:07 +0800 Subject: [PATCH 137/172] Refactor code in taskbarHost --- atom/browser/api/atom_api_window.cc | 10 ++- atom/browser/api/atom_api_window.h | 2 +- atom/browser/ui/win/taskbar_host.cc | 128 ++++++++++++++-------------- atom/browser/ui/win/taskbar_host.h | 11 ++- docs/api/browser-window.md | 29 ++++--- 5 files changed, 92 insertions(+), 88 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 2cbe8be566e2..6ff1dfc00628 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -438,16 +438,18 @@ void Window::SetOverlayIcon(const gfx::Image& overlay, window_->SetOverlayIcon(overlay, description); } -void Window::SetThumbarButtons(mate::Arguments* args) { +bool Window::SetThumbarButtons(mate::Arguments* args) { #if defined(OS_WIN) std::vector buttons; if (!args->GetNext(&buttons)) { args->ThrowError(); - return; + return false; } auto window = static_cast(window_.get()); - window->taskbar_host().SetThumbarButtons(window->GetAcceleratedWidget(), - buttons); + return window->taskbar_host().SetThumbarButtons( + window->GetAcceleratedWidget(), buttons); +#else + return false; #endif } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 389c03ab9d40..de2f093ea3e1 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -130,7 +130,7 @@ class Window : public mate::TrackableObject, void SetProgressBar(double progress); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); - void SetThumbarButtons(mate::Arguments* args); + bool SetThumbarButtons(mate::Arguments* args); void SetMenu(v8::Isolate* isolate, v8::Local menu); void SetAutoHideMenuBar(bool auto_hide); bool IsMenuBarAutoHide(); diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index 3173215a4f6b..a6ab44d0723d 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -8,49 +8,40 @@ #include +#include "base/stl_util.h" #include "base/win/scoped_comptr.h" -#include "base/win/win_util.h" -#include "base/win/wrapped_window_proc.h" +#include "base/win/scoped_gdi_object.h" #include "base/strings/utf_string_conversions.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/icon_util.h" -#include "ui/gfx/win/hwnd_util.h" namespace atom { namespace { -// From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ -// dd378460(v=vs.85).aspx#thumbbars +// From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#thumbbars // The thumbnail toolbar has a maximum of seven buttons due to the limited room. -const int kMaxButtonsCount = 7; +const size_t kMaxButtonsCount = 7; // The base id of Thumbar button. const int kButtonIdBase = 40001; bool GetThumbarButtonFlags(const std::vector& flags, THUMBBUTTONFLAGS* out) { - if (flags.empty()) { - *out = THBF_ENABLED; - return true; - } - THUMBBUTTONFLAGS result = static_cast(0); + THUMBBUTTONFLAGS result = THBF_ENABLED; // THBF_ENABLED == 0 for (const auto& flag : flags) { - if (flag == "enabled") { - result |= THBF_ENABLED; - } else if (flag == "disabled") { + if (flag == "disabled") result |= THBF_DISABLED; - } else if (flag == "dismissonclick") { + else if (flag == "dismissonclick") result |= THBF_DISMISSONCLICK; - } else if (flag == "nobackground") { + else if (flag == "nobackground") result |= THBF_NOBACKGROUND; - } else if (flag == "hidden") { + else if (flag == "hidden") result |= THBF_HIDDEN; - } else if (flag == "noninteractive") { + else if (flag == "noninteractive") result |= THBF_NONINTERACTIVE; - } else { + else return false; - } } *out = result; return true; @@ -58,7 +49,7 @@ bool GetThumbarButtonFlags(const std::vector& flags, } // namespace -TaskbarHost::TaskbarHost() : is_initialized_(false) { +TaskbarHost::TaskbarHost() : thumbar_buttons_added_(false) { } TaskbarHost::~TaskbarHost() { @@ -66,9 +57,6 @@ TaskbarHost::~TaskbarHost() { bool TaskbarHost::SetThumbarButtons( HWND window, const std::vector& buttons) { - if (buttons.size() > kMaxButtonsCount) - return false; - base::win::ScopedComPtr taskbar; if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, nullptr, @@ -77,59 +65,67 @@ bool TaskbarHost::SetThumbarButtons( return false; } + callback_map_.clear(); + + // The number of buttons in thumbar can not be changed once it is created, + // so we have to claim kMaxButtonsCount buttons initialy in case users add + // more buttons later. + base::win::ScopedHICON icons[kMaxButtonsCount] = {}; THUMBBUTTON thumb_buttons[kMaxButtonsCount] = {}; - thumbar_button_clicked_callback_map_.clear(); - // Once a toolbar with a set of buttons is added to thumbnail, there is no way - // to remove it without re-creating the window. - // To achieve to re-set thumbar buttons, we initialize the buttons with - // HIDDEN state and only updated the caller's specified buttons. - // - // Initialize all thumb buttons with HIDDEN state. - for (int i = 0; i < kMaxButtonsCount; ++i) { - thumb_buttons[i].iId = kButtonIdBase + i; - thumb_buttons[i].dwMask = THB_FLAGS; // dwFlags is valid. - thumb_buttons[i].dwFlags = THBF_HIDDEN; - } + for (size_t i = 0; i < kMaxButtonsCount; ++i) { + THUMBBUTTON& thumb_button = thumb_buttons[i]; - // Update the callers' specified buttons. - for (size_t i = 0; i < buttons.size(); ++i) { - if (!GetThumbarButtonFlags(buttons[i].flags, &thumb_buttons[i].dwFlags)) - return false; - thumb_buttons[i].dwMask = THB_ICON | THB_FLAGS; - thumb_buttons[i].hIcon = IconUtil::CreateHICONFromSkBitmap( - buttons[i].icon.AsBitmap()); - if (!buttons[i].tooltip.empty()) { - thumb_buttons[i].dwMask |= THB_TOOLTIP; - wcscpy_s(thumb_buttons[i].szTip, - base::UTF8ToUTF16(buttons[i].tooltip).c_str()); + // Set ID. + thumb_button.iId = kButtonIdBase + i; + thumb_button.dwMask = THB_FLAGS; + + if (i >= buttons.size()) { + // This button is used to occupy the place in toolbar, and it does not + // show. + thumb_button.dwFlags = THBF_HIDDEN; + continue; } - thumbar_button_clicked_callback_map_[thumb_buttons[i].iId] = - buttons[i].clicked_callback; + // This button is user's button. + const ThumbarButton& button = buttons[i]; + + // Generate flags. + thumb_button.dwFlags = THBF_ENABLED; + if (!GetThumbarButtonFlags(button.flags, &thumb_button.dwFlags)) + return false; + + // Set icon. + if (!button.icon.IsEmpty()) { + thumb_button.dwMask |= THB_ICON; + icons[i] = IconUtil::CreateHICONFromSkBitmap(button.icon.AsBitmap()); + thumb_button.hIcon = icons[i].Get(); + } + + // Set tooltip. + if (!button.tooltip.empty()) { + thumb_button.dwMask |= THB_TOOLTIP; + wcscpy_s(thumb_button.szTip, base::UTF8ToUTF16(button.tooltip).c_str()); + } + + // Save callback. + callback_map_[thumb_button.iId] = button.clicked_callback; } - bool is_success = false; - if (!is_initialized_) { - is_initialized_ = true; - is_success = taskbar->ThumbBarAddButtons( - window, buttons.size(), thumb_buttons) == S_OK; - } else { - is_success = taskbar->ThumbBarUpdateButtons( - window, kMaxButtonsCount, thumb_buttons) == S_OK; - } + // Finally add them to taskbar. + HRESULT r; + if (thumbar_buttons_added_) + r = taskbar->ThumbBarUpdateButtons(window, kMaxButtonsCount, thumb_buttons); + else + r = taskbar->ThumbBarAddButtons(window, kMaxButtonsCount, thumb_buttons); - // Release thumb_buttons' icons, the taskbar makes its own copy. - for (size_t i = 0; i < buttons.size(); ++i) { - ::DestroyIcon(thumb_buttons[i].hIcon); - } - return is_success; + thumbar_buttons_added_ = true; + return SUCCEEDED(r); } bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { - if (thumbar_button_clicked_callback_map_.find(button_id) != - thumbar_button_clicked_callback_map_.end()) { - auto callback = thumbar_button_clicked_callback_map_[button_id]; + if (ContainsKey(callback_map_, button_id)) { + auto callback = callback_map_[button_id]; if (!callback.is_null()) callback.Run(); return true; diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index 2c81a9cdb371..f3172902af11 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -8,6 +8,7 @@ #include #include +#include #include #include "base/callback.h" @@ -27,15 +28,19 @@ class TaskbarHost { TaskbarHost(); virtual ~TaskbarHost(); + // Add or update the buttons in thumbar bool SetThumbarButtons( HWND window, const std::vector& buttons); + + // Called by the window that there is a button in thumbar clicked. bool HandleThumbarButtonEvent(int button_id); private: - using ThumbarButtonClickedCallbackMap = std::map; - ThumbarButtonClickedCallbackMap thumbar_button_clicked_callback_map_; + using CallbackMap = std::map; + CallbackMap callback_map_; - bool is_initialized_; + // Whether we have already added the buttons to thumbar. + bool thumbar_buttons_added_; DISALLOW_COPY_AND_ASSIGN(TaskbarHost); }; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 60b9b84735d0..612b3ce4f3f0 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -646,23 +646,24 @@ __Note:__ This API is only available on Windows (Windows 7 and above) ### BrowserWindow.setThumbarButtons(buttons) -* `buttons` Array of `button` objects +* `buttons` Array * `button` Object * `icon` [NativeImage](native-image.md) - The icon showing in thumbnail toolbar. - * `tooltip` String - (Option) - The text of the button's tooltip. - * `flags` Array of Strings - (Option) Control specific states and behaviors - of the button. By default, it uses `enabled`. - * `enabled` - The button is active and available to the user. - * `disabled` - The button is disabled. It is present, but has a visual - state that indicates that it will not respond to user action. - * `dismissonclick` - When the button is clicked, the taskbar button's - flyout closes immediately. - * `nobackground` - Do not draw a button border, use only the image. - * `hidden` - The button is not shown to the user. - * `noninteractive` - The button is enabled but not interactive; no - pressed button state is drawn. This value is intended for instances - where the button is used in a notification. + * `tooltip` String (optional) - The text of the button's tooltip. + * `flags` Array (optional) - Control specific states and behaviors + of the button. By default, it uses `enabled`. It can include following + Strings: + * `enabled` - The button is active and available to the user. + * `disabled` - The button is disabled. It is present, but has a visual + state that indicates that it will not respond to user action. + * `dismissonclick` - When the button is clicked, the taskbar button's + flyout closes immediately. + * `nobackground` - Do not draw a button border, use only the image. + * `hidden` - The button is not shown to the user. + * `noninteractive` - The button is enabled but not interactive; no + pressed button state is drawn. This value is intended for instances + where the button is used in a notification. * `click` - Function Add a thumbnail toolbar with a specified set of buttons to the thumbnail image From 2d6f8350cb5ac89f7527449e823196084256f761 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 12:54:00 +0800 Subject: [PATCH 138/172] Move SetProgressBar to TaskbarHost --- atom/browser/native_window_views.cc | 19 +------------------ atom/browser/ui/win/taskbar_host.cc | 19 +++++++++++++++++++ atom/browser/ui/win/taskbar_host.h | 5 ++++- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 759249e5aa4e..868ca5da1929 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -621,24 +621,7 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() { void NativeWindowViews::SetProgressBar(double progress) { #if defined(OS_WIN) - if (base::win::GetVersion() < base::win::VERSION_WIN7) - return; - base::win::ScopedComPtr taskbar; - if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, NULL, - CLSCTX_INPROC_SERVER) || - FAILED(taskbar->HrInit()))) { - return; - } - HWND frame = views::HWNDForNativeWindow(GetNativeWindow()); - if (progress > 1.0) { - taskbar->SetProgressState(frame, TBPF_INDETERMINATE); - } else if (progress < 0) { - taskbar->SetProgressState(frame, TBPF_NOPROGRESS); - } else if (progress >= 0) { - taskbar->SetProgressValue(frame, - static_cast(progress * 100), - 100); - } + taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress); #elif defined(USE_X11) if (unity::IsRunning()) { unity::SetProgressFraction(progress); diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index a6ab44d0723d..e3ee3fcd47c6 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -123,6 +123,25 @@ bool TaskbarHost::SetThumbarButtons( return SUCCEEDED(r); } +bool TaskbarHost::SetProgressBar(HWND window, double value) { + base::win::ScopedComPtr taskbar; + if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, + nullptr, + CLSCTX_INPROC_SERVER)) || + FAILED(taskbar->HrInit())) { + return false; + } + + HRESULT r; + if (value > 1.0) + r = taskbar->SetProgressState(window, TBPF_INDETERMINATE); + else if (value < 0) + r = taskbar->SetProgressState(window, TBPF_NOPROGRESS); + else + r= taskbar->SetProgressValue(window, static_cast(value * 100), 100); + return SUCCEEDED(r); +} + bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { if (ContainsKey(callback_map_, button_id)) { auto callback = callback_map_[button_id]; diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index f3172902af11..22ea4cbb31a2 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -28,10 +28,13 @@ class TaskbarHost { TaskbarHost(); virtual ~TaskbarHost(); - // Add or update the buttons in thumbar + // Add or update the buttons in thumbar. bool SetThumbarButtons( HWND window, const std::vector& buttons); + // Sets the progress state in taskbar. + bool SetProgressBar(HWND window, double value); + // Called by the window that there is a button in thumbar clicked. bool HandleThumbarButtonEvent(int button_id); From 8da7803f3e488d918507560d9e6c203e5fd0dee1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 12:58:40 +0800 Subject: [PATCH 139/172] Save the taskbar object --- atom/browser/ui/win/taskbar_host.cc | 39 ++++++++++++++--------------- atom/browser/ui/win/taskbar_host.h | 9 ++++++- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index e3ee3fcd47c6..1ffc567f7b00 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -4,12 +4,9 @@ #include "atom/browser/ui/win/taskbar_host.h" -#include - #include #include "base/stl_util.h" -#include "base/win/scoped_comptr.h" #include "base/win/scoped_gdi_object.h" #include "base/strings/utf_string_conversions.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -57,13 +54,8 @@ TaskbarHost::~TaskbarHost() { bool TaskbarHost::SetThumbarButtons( HWND window, const std::vector& buttons) { - base::win::ScopedComPtr taskbar; - if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, - nullptr, - CLSCTX_INPROC_SERVER)) || - FAILED(taskbar->HrInit())) { + if (!InitailizeTaskbar()) return false; - } callback_map_.clear(); @@ -115,30 +107,26 @@ bool TaskbarHost::SetThumbarButtons( // Finally add them to taskbar. HRESULT r; if (thumbar_buttons_added_) - r = taskbar->ThumbBarUpdateButtons(window, kMaxButtonsCount, thumb_buttons); + r = taskbar_->ThumbBarUpdateButtons(window, kMaxButtonsCount, + thumb_buttons); else - r = taskbar->ThumbBarAddButtons(window, kMaxButtonsCount, thumb_buttons); + r = taskbar_->ThumbBarAddButtons(window, kMaxButtonsCount, thumb_buttons); thumbar_buttons_added_ = true; return SUCCEEDED(r); } bool TaskbarHost::SetProgressBar(HWND window, double value) { - base::win::ScopedComPtr taskbar; - if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, - nullptr, - CLSCTX_INPROC_SERVER)) || - FAILED(taskbar->HrInit())) { + if (!InitailizeTaskbar()) return false; - } HRESULT r; if (value > 1.0) - r = taskbar->SetProgressState(window, TBPF_INDETERMINATE); + r = taskbar_->SetProgressState(window, TBPF_INDETERMINATE); else if (value < 0) - r = taskbar->SetProgressState(window, TBPF_NOPROGRESS); + r = taskbar_->SetProgressState(window, TBPF_NOPROGRESS); else - r= taskbar->SetProgressValue(window, static_cast(value * 100), 100); + r= taskbar_->SetProgressValue(window, static_cast(value * 100), 100); return SUCCEEDED(r); } @@ -152,4 +140,15 @@ bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { return false; } +bool TaskbarHost::InitailizeTaskbar() { + if (FAILED(taskbar_.CreateInstance(CLSID_TaskbarList, + nullptr, + CLSCTX_INPROC_SERVER)) || + FAILED(taskbar_->HrInit())) { + return false; + } else { + return true; + } +} + } // namespace atom diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index 22ea4cbb31a2..755f867eb132 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -5,13 +5,14 @@ #ifndef ATOM_BROWSER_UI_WIN_TASKBAR_HOST_H_ #define ATOM_BROWSER_UI_WIN_TASKBAR_HOST_H_ -#include +#include #include #include #include #include "base/callback.h" +#include "base/win/scoped_comptr.h" #include "ui/gfx/image/image.h" namespace atom { @@ -39,9 +40,15 @@ class TaskbarHost { bool HandleThumbarButtonEvent(int button_id); private: + // Initailize the taskbar object. + bool InitailizeTaskbar(); + using CallbackMap = std::map; CallbackMap callback_map_; + // The COM object of taskbar. + base::win::ScopedComPtr taskbar_; + // Whether we have already added the buttons to thumbar. bool thumbar_buttons_added_; From 6e75af5c0f159981ce44eadae618976895119696 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 13:07:00 +0800 Subject: [PATCH 140/172] Move SetOverlayIcon to TaskbarHost --- atom/browser/native_window_views.cc | 25 +------------------------ atom/browser/ui/win/taskbar_host.cc | 11 +++++++++++ atom/browser/ui/win/taskbar_host.h | 6 +++++- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 868ca5da1929..45697c96683c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -4,10 +4,6 @@ #include "atom/browser/native_window_views.h" -#if defined(OS_WIN) -#include -#endif - #include #include @@ -46,13 +42,9 @@ #elif defined(OS_WIN) #include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" -#include "base/win/scoped_comptr.h" -#include "base/win/windows_version.h" #include "ui/base/win/shell.h" -#include "ui/gfx/icon_util.h" #include "ui/gfx/win/dpi.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" -#include "ui/views/win/hwnd_util.h" #endif namespace atom { @@ -632,22 +624,7 @@ void NativeWindowViews::SetProgressBar(double progress) { void NativeWindowViews::SetOverlayIcon(const gfx::Image& overlay, const std::string& description) { #if defined(OS_WIN) - if (base::win::GetVersion() < base::win::VERSION_WIN7) - return; - - base::win::ScopedComPtr taskbar; - if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, NULL, - CLSCTX_INPROC_SERVER) || - FAILED(taskbar->HrInit()))) { - return; - } - - HWND frame = views::HWNDForNativeWindow(GetNativeWindow()); - - std::wstring wstr = std::wstring(description.begin(), description.end()); - taskbar->SetOverlayIcon(frame, - IconUtil::CreateHICONFromSkBitmap(overlay.AsBitmap()), - wstr.c_str()); + taskbar_host_.SetOverlayIcon(GetAcceleratedWidget(), overlay, description); #endif } diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index 1ffc567f7b00..edbc78ce5c83 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -130,6 +130,17 @@ bool TaskbarHost::SetProgressBar(HWND window, double value) { return SUCCEEDED(r); } +bool TaskbarHost::SetOverlayIcon( + HWND window, const gfx::Image& overlay, const std::string& text) { + if (!InitailizeTaskbar()) + return false; + + base::win::ScopedHICON icon( + IconUtil::CreateHICONFromSkBitmap(overlay.AsBitmap())); + return SUCCEEDED( + taskbar_->SetOverlayIcon(window, icon, base::UTF8ToUTF16(text).c_str())); +} + bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { if (ContainsKey(callback_map_, button_id)) { auto callback = callback_map_[button_id]; diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index 755f867eb132..185b88a6b5b6 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -33,9 +33,13 @@ class TaskbarHost { bool SetThumbarButtons( HWND window, const std::vector& buttons); - // Sets the progress state in taskbar. + // Set the progress state in taskbar. bool SetProgressBar(HWND window, double value); + // Set the overlay icon in taskbar. + bool SetOverlayIcon( + HWND window, const gfx::Image& overlay, const std::string& text); + // Called by the window that there is a button in thumbar clicked. bool HandleThumbarButtonEvent(int button_id); From 454085eb95d854c3bfbe5785e88536715e96e266 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 13:07:39 +0800 Subject: [PATCH 141/172] Fix cpplint warning --- atom/browser/ui/win/taskbar_host.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index edbc78ce5c83..c728e4664c3a 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -126,7 +126,7 @@ bool TaskbarHost::SetProgressBar(HWND window, double value) { else if (value < 0) r = taskbar_->SetProgressState(window, TBPF_NOPROGRESS); else - r= taskbar_->SetProgressValue(window, static_cast(value * 100), 100); + r = taskbar_->SetProgressValue(window, static_cast(value * 100), 100); return SUCCEEDED(r); } From 744059b8bd8132d5fd1cfd757accc60b45ba55e2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Aug 2015 15:22:17 +0800 Subject: [PATCH 142/172] Check button size --- atom/browser/ui/win/taskbar_host.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index c728e4664c3a..a8e6ff2926cd 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -54,7 +54,7 @@ TaskbarHost::~TaskbarHost() { bool TaskbarHost::SetThumbarButtons( HWND window, const std::vector& buttons) { - if (!InitailizeTaskbar()) + if (buttons.size() > kMaxButtonsCount || !InitailizeTaskbar()) return false; callback_map_.clear(); From fb60f7946fe3bd6562aed26c2a2a6d120e49de5a Mon Sep 17 00:00:00 2001 From: Alex Ryan Date: Thu, 6 Aug 2015 22:15:59 -0700 Subject: [PATCH 143/172] Fixed typo --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index 7e47b446f6d3..8223643a375f 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -23,7 +23,7 @@ In most cases, you should just do everything in the `ready` event handler. ## Event: ready -Emitted when Electron has finsished initialization. +Emitted when Electron has finished initialization. ## Event: window-all-closed From 24ba712aa5ae47d95ec45cc964b53882ee6e8c06 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 19:35:12 +0800 Subject: [PATCH 144/172] Update libchromiumcontent to have WebScopedRunV8Script --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 82640153a17c..144ec87c677b 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '8c7f5b9adb9372130a9295b7e0fb19355f613cf9' +LIBCHROMIUMCONTENT_COMMIT = 'dd51a41b42246b0b5159bfad5e327c8cf10bc585' PLATFORM = { 'cygwin': 'win32', From 5d3445cebb23eef45cc68508cefa4626e82160d7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 15:06:09 +0800 Subject: [PATCH 145/172] Style fix --- atom/renderer/atom_render_view_observer.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index eb59fe03d3b3..686481327f5b 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -162,8 +162,7 @@ void AtomRenderViewObserver::OnJavaScriptExecuteRequest( v8::HandleScope handle_scope(isolate); blink::WebFrame* frame = render_view()->GetWebView()->mainFrame(); - frame->executeScriptAndReturnValue( - blink::WebScriptSource(code)); + frame->executeScriptAndReturnValue(blink::WebScriptSource(code)); } } // namespace atom From ab44edd2948b2e133b6ba64b717ac974935618f5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 15:10:14 +0800 Subject: [PATCH 146/172] Perform microtask checkpoint after diving into libuv --- atom/common/node_bindings.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 8f5dd07428ad..b329589552ba 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -19,6 +19,7 @@ #include "content/public/common/content_paths.h" #include "native_mate/locker.h" #include "native_mate/dictionary.h" +#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" #include "atom/common/node_includes.h" @@ -227,6 +228,10 @@ void NodeBindings::UvRunOnce() { // Enter node context while dealing with uv events. v8::Context::Scope context_scope(env->context()); + // Perform microtask checkpoint after running JavaScript. + scoped_ptr script_scope( + is_browser_ ? nullptr : new blink::WebScopedRunV8Script(env->isolate())); + // Deal with uv events. int r = uv_run(uv_loop_, UV_RUN_NOWAIT); if (r == 0 || uv_loop_->stop_flag != 0) From 74fa2c809d7727d3ff792b7f29abd5a797be1095 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 15:18:33 +0800 Subject: [PATCH 147/172] Make every JS function call is wrapped with V8RecursionScope --- atom/common/event_emitter_caller.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/atom/common/event_emitter_caller.cc b/atom/common/event_emitter_caller.cc index 3dbdc9db956d..68c48217a364 100644 --- a/atom/common/event_emitter_caller.cc +++ b/atom/common/event_emitter_caller.cc @@ -4,15 +4,33 @@ #include "atom/common/event_emitter_caller.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" + #include "atom/common/node_includes.h" namespace mate { namespace internal { +namespace { + +// Returns whether current process is browser process, currently we detect it +// by checking whether current has used V8 Lock, but it might be a bad idea. +inline bool IsBrowserProcess() { + return v8::Locker::IsActive(); +} + +} // namespace + v8::Local CallEmitWithArgs(v8::Isolate* isolate, v8::Local obj, ValueVector* args) { + // Perform microtask checkpoint after running JavaScript. + scoped_ptr script_scope( + IsBrowserProcess() ? nullptr : new blink::WebScopedRunV8Script(isolate)); + // Use node::MakeCallback to call the callback, and it will also run pending + // tasks in Node.js. return node::MakeCallback( isolate, obj, "emit", args->size(), &args->front()); } From 3402871741e5b4517664fc479f6e483c9d2d1a42 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 16:55:16 +0800 Subject: [PATCH 148/172] spec: Check the time when Promise's callback is called --- spec/chromium-spec.coffee | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index 32fd5bed6742..704e5bbcac74 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -135,3 +135,32 @@ describe 'chromium feature', -> else done('user agent is empty') websocket = new WebSocket("ws://127.0.0.1:#{port}") + + describe 'Promise', -> + it 'resolves correctly in Node.js calls', (done) -> + document.registerElement('x-element', { + prototype: Object.create(HTMLElement.prototype, { + createdCallback: { value: -> } + }) + }) + + setImmediate -> + called = false + Promise.resolve().then -> + done(if called then undefined else new Error('wrong sequnce')) + document.createElement 'x-element' + called = true + + it 'resolves correctly in Electron calls', (done) -> + document.registerElement('y-element', { + prototype: Object.create(HTMLElement.prototype, { + createdCallback: { value: -> } + }) + }) + + remote.getGlobal('setImmediate') -> + called = false + Promise.resolve().then -> + done(if called then undefined else new Error('wrong sequnce')) + document.createElement 'y-element' + called = true From 2ff104d0125e3434cc1a0e6de57cc9938c70481a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 18:10:19 +0800 Subject: [PATCH 149/172] Move callback converter from native mate to electron --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/atom_api_content_tracing.cc | 2 +- atom/browser/api/atom_api_cookies.cc | 2 +- atom/browser/api/atom_api_dialog.cc | 2 +- atom/browser/api/atom_api_global_shortcut.cc | 2 +- atom/browser/api/atom_api_menu.cc | 2 +- atom/browser/api/atom_api_protocol.cc | 2 +- atom/browser/api/atom_api_session.cc | 2 +- atom/browser/api/atom_api_web_contents.cc | 2 +- atom/browser/api/atom_api_window.cc | 2 +- atom/common/api/atom_api_asar.cc | 2 +- atom/common/native_mate_converters/callback.h | 439 ++++++++++++++++++ atom/renderer/api/atom_api_web_frame.cc | 2 +- filenames.gypi | 1 + vendor/native_mate | 2 +- 15 files changed, 453 insertions(+), 13 deletions(-) create mode 100644 atom/common/native_mate_converters/callback.h diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index fea4deda5b1b..c25b3be5f4d6 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -17,6 +17,7 @@ #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/browser.h" #include "atom/browser/api/atom_api_web_contents.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "base/command_line.h" #include "base/environment.h" @@ -25,7 +26,6 @@ #include "brightray/browser/brightray_paths.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/ssl/ssl_cert_request_info.h" diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index 9507d19d399a..e404a8f26ca6 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -5,11 +5,11 @@ #include #include +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "base/bind.h" #include "base/files/file_util.h" #include "content/public/browser/tracing_controller.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 0363032df878..040efe1c360b 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -4,13 +4,13 @@ #include "atom/browser/api/atom_api_cookies.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "base/bind.h" #include "base/time/time.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/cookies/cookie_monster.h" diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 47021407e1ea..40ee4d0d9b51 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -10,9 +10,9 @@ #include "atom/browser/native_window.h" #include "atom/browser/ui/file_dialog.h" #include "atom/browser/ui/message_box.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/image_converter.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index 47bebe9d12bd..f5a03e4abf90 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -7,8 +7,8 @@ #include #include "atom/common/native_mate_converters/accelerator_converter.h" +#include "atom/common/native_mate_converters/callback.h" #include "base/stl_util.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index 1eb5cb31d118..915e152b3a68 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -6,9 +6,9 @@ #include "atom/browser/native_window.h" #include "atom/common/native_mate_converters/accelerator_converter.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" -#include "native_mate/callback.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 53aef95b7657..1241a95a718f 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -10,10 +10,10 @@ #include "atom/browser/api/atom_api_session.h" #include "atom/browser/net/adapter_request_job.h" #include "atom/browser/net/atom_url_request_job_factory.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "content/public/browser/browser_thread.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "net/url_request/url_request_context.h" diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 19efd2d32ac8..b8b1434dd70d 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/atom_browser_context.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "base/files/file_path.h" @@ -18,7 +19,6 @@ #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" -#include "native_mate/callback.h" #include "native_mate/object_template_builder.h" #include "net/base/load_flags.h" #include "net/disk_cache/disk_cache.h" diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1f68a4d8ad1d..6adcf5377357 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -14,6 +14,7 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" #include "atom/common/event_emitter_caller.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" @@ -37,7 +38,6 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/http/http_response_headers.h" diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6ff1dfc00628..e6d16fe6fa59 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,12 +8,12 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "content/public/browser/render_process_host.h" -#include "native_mate/callback.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 07d7c608d16d..24e9ce9b0668 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -8,9 +8,9 @@ #include "atom_natives.h" // NOLINT: This file is generated with coffee2c. #include "atom/common/asar/archive.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "native_mate/arguments.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "native_mate/wrappable.h" diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h new file mode 100644 index 000000000000..5dfcf9b25136 --- /dev/null +++ b/atom/common/native_mate_converters/callback.h @@ -0,0 +1,439 @@ +// Copyright (c) 2015 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/callback.h" +#include "native_mate/function_template.h" +#include "native_mate/locker.h" +#include "native_mate/scoped_persistent.h" + +namespace mate { + +namespace internal { + +typedef scoped_refptr > SafeV8Function; + +// This set of templates invokes a V8::Function by converting the C++ types. +template +struct V8FunctionInvoker; + +template +struct V8FunctionInvoker()> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local val(holder->Call(holder, 0, NULL)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local val(holder->Call(holder, 0, NULL)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template<> +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + holder->Call(holder, 0, NULL); + } +}; + +template +struct V8FunctionInvoker(P1)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker(P1, P2)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, + P2 a2) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker(P1, P2, P3)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, + P2 a2, P3 a3) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker(P1, P2, P3, P4)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, + P2 a2, P3 a3, P4 a4) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker(P1, P2, P3, P4, P5)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, + P2 a2, P3 a3, P4 a4, P5 a5) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4, P5 a5) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4, P5 a5) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +template +struct V8FunctionInvoker(P1, P2, P3, P4, P5, P6)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, + P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { + Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + ConvertToV8(isolate, a6), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + return handle_scope.Escape(val); + } +}; + +template +struct V8FunctionInvoker { + static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4, P5 a5, P6 a6) { + R ret; + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + ConvertToV8(isolate, a6), + }; + v8::Local val(holder->Call(holder, arraysize(args), args)); + Converter::FromV8(isolate, val, &ret); + return ret; + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, + P3 a3, P4 a4, P5 a5, P6 a6) { + Locker locker(isolate); + MATE_HANDLE_SCOPE(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + v8::Local args[] = { + ConvertToV8(isolate, a1), + ConvertToV8(isolate, a2), + ConvertToV8(isolate, a3), + ConvertToV8(isolate, a4), + ConvertToV8(isolate, a5), + ConvertToV8(isolate, a6), + }; + holder->Call(holder, arraysize(args), args); + } +}; + +} // namespace internal + +template +struct Converter > { + static v8::Local ToV8(v8::Isolate* isolate, + const base::Callback& val) { + return CreateFunctionTemplate(isolate, val)->GetFunction(); + } + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::Callback* out) { + if (!val->IsFunction()) + return false; + + internal::SafeV8Function function( + new RefCountedPersistent(isolate, val)); + *out = base::Bind(&internal::V8FunctionInvoker::Go, isolate, function); + return true; + } +}; + +} // namespace mate diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 783650516bfa..d2c4ed2fa7b0 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -4,11 +4,11 @@ #include "atom/renderer/api/atom_api_web_frame.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" #include "content/public/renderer/render_frame.h" -#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "third_party/WebKit/public/web/WebDocument.h" diff --git a/filenames.gypi b/filenames.gypi index f7b9fca5e717..977eb1686fd9 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -274,6 +274,7 @@ 'atom/common/linux/application_info.cc', 'atom/common/native_mate_converters/accelerator_converter.cc', 'atom/common/native_mate_converters/accelerator_converter.h', + 'atom/common/native_mate_converters/callback.h', 'atom/common/native_mate_converters/file_path_converter.h', 'atom/common/native_mate_converters/gfx_converter.cc', 'atom/common/native_mate_converters/gfx_converter.h', diff --git a/vendor/native_mate b/vendor/native_mate index 656e403f0102..ebcf4c022467 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 656e403f0102c59428261c1eaad22912d2bbd3c5 +Subproject commit ebcf4c022467a43a5379446e1c031ffd10438b9c From 5c18d894530cf84bdcfa1890a485216f4a1cee38 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 19:15:36 +0800 Subject: [PATCH 150/172] Reimplement callback.h with C++11 --- atom/common/native_mate_converters/callback.h | 418 ++---------------- 1 file changed, 34 insertions(+), 384 deletions(-) diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index 5dfcf9b25136..e7dc6af249f8 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -2,6 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. +#include + #include "base/bind.h" #include "base/callback.h" #include "native_mate/function_template.h" @@ -14,407 +16,55 @@ namespace internal { typedef scoped_refptr > SafeV8Function; -// This set of templates invokes a V8::Function by converting the C++ types. -template -struct V8FunctionInvoker; +template +struct V8FunctionInvoker {}; -template -struct V8FunctionInvoker()> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function) { +template +struct V8FunctionInvoker(ArgTypes...)> { + static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, + ArgTypes... raw) { Locker locker(isolate); v8::EscapableHandleScope handle_scope(isolate); v8::Local holder = function->NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - v8::Local val(holder->Call(holder, 0, NULL)); - return handle_scope.Escape(val); + std::vector> args = { ConvertToV8(isolate, raw)... }; + v8::Local ret(holder->Call(holder, args.size(), &args.front())); + return handle_scope.Escape(ret); } }; -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function) { - R ret; +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, SafeV8Function function, + ArgTypes... raw) { Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); + v8::HandleScope handle_scope(isolate); v8::Local holder = function->NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - v8::Local val(holder->Call(holder, 0, NULL)); - Converter::FromV8(isolate, val, &ret); + std::vector> args = { ConvertToV8(isolate, raw)... }; + holder->Call(holder, args.size(), &args.front()); + } +}; + +template +struct V8FunctionInvoker { + static ReturnType Go(v8::Isolate* isolate, SafeV8Function function, + ArgTypes... raw) { + Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + v8::Local holder = function->NewHandle(); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + ReturnType ret; + std::vector> args = { ConvertToV8(isolate, raw)... }; + v8::Local val(holder->Call(holder, args.size(), &args.front())); + Converter::FromV8(isolate, val, &ret); return ret; } }; -template<> -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - holder->Call(holder, 0, NULL); - } -}; - -template -struct V8FunctionInvoker(P1)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - }; - holder->Call(holder, arraysize(args), args); - } -}; - -template -struct V8FunctionInvoker(P1, P2)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, - P2 a2) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - }; - holder->Call(holder, arraysize(args), args); - } -}; - -template -struct V8FunctionInvoker(P1, P2, P3)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, - P2 a2, P3 a3) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - }; - holder->Call(holder, arraysize(args), args); - } -}; - -template -struct V8FunctionInvoker(P1, P2, P3, P4)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, - P2 a2, P3 a3, P4 a4) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - }; - holder->Call(holder, arraysize(args), args); - } -}; - -template -struct V8FunctionInvoker(P1, P2, P3, P4, P5)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, - P2 a2, P3 a3, P4 a4, P5 a5) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4, P5 a5) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4, P5 a5) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - }; - holder->Call(holder, arraysize(args), args); - } -}; - -template -struct V8FunctionInvoker(P1, P2, P3, P4, P5, P6)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, - P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { - Locker locker(isolate); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - ConvertToV8(isolate, a6), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - return handle_scope.Escape(val); - } -}; - -template -struct V8FunctionInvoker { - static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4, P5 a5, P6 a6) { - R ret; - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - ConvertToV8(isolate, a6), - }; - v8::Local val(holder->Call(holder, arraysize(args), args)); - Converter::FromV8(isolate, val, &ret); - return ret; - } -}; - -template -struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2, - P3 a3, P4 a4, P5 a5, P6 a6) { - Locker locker(isolate); - MATE_HANDLE_SCOPE(isolate); - v8::Local holder = function->NewHandle(); - v8::Local context = holder->CreationContext(); - v8::Context::Scope context_scope(context); - v8::Local args[] = { - ConvertToV8(isolate, a1), - ConvertToV8(isolate, a2), - ConvertToV8(isolate, a3), - ConvertToV8(isolate, a4), - ConvertToV8(isolate, a5), - ConvertToV8(isolate, a6), - }; - holder->Call(holder, arraysize(args), args); - } -}; - } // namespace internal template From 1bb0dde360e0da83f955aba4407b4d9a6a9ce6e6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 19:34:00 +0800 Subject: [PATCH 151/172] Use WebScopedRunV8Script in converted C++ functions --- atom/browser/api/atom_api_web_contents.cc | 2 +- atom/browser/api/event_emitter.h | 2 +- atom/common/{ => api}/event_emitter_caller.cc | 16 +++------ atom/common/{ => api}/event_emitter_caller.h | 6 ++-- atom/common/api/locker.cc | 17 ++++++++++ atom/common/api/locker.h | 34 +++++++++++++++++++ atom/common/native_mate_converters/callback.h | 17 +++++++++- atom/common/node_bindings.cc | 4 +-- atom/renderer/atom_render_view_observer.cc | 2 +- filenames.gypi | 6 ++-- script/lib/config.py | 2 +- vendor/native_mate | 2 +- 12 files changed, 85 insertions(+), 25 deletions(-) rename atom/common/{ => api}/event_emitter_caller.cc (69%) rename atom/common/{ => api}/event_emitter_caller.h (92%) create mode 100644 atom/common/api/locker.cc create mode 100644 atom/common/api/locker.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 6adcf5377357..63707f8dcc2d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -13,7 +13,7 @@ #include "atom/browser/native_window.h" #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" -#include "atom/common/event_emitter_caller.h" +#include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 178c61d853ca..4fb953b63992 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -7,7 +7,7 @@ #include -#include "atom/common/event_emitter_caller.h" +#include "atom/common/api/event_emitter_caller.h" #include "native_mate/wrappable.h" namespace content { diff --git a/atom/common/event_emitter_caller.cc b/atom/common/api/event_emitter_caller.cc similarity index 69% rename from atom/common/event_emitter_caller.cc rename to atom/common/api/event_emitter_caller.cc index 68c48217a364..6b0a07ad414a 100644 --- a/atom/common/event_emitter_caller.cc +++ b/atom/common/api/event_emitter_caller.cc @@ -2,8 +2,9 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "atom/common/event_emitter_caller.h" +#include "atom/common/api/event_emitter_caller.h" +#include "atom/common/api/locker.h" #include "base/memory/scoped_ptr.h" #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" @@ -13,22 +14,13 @@ namespace mate { namespace internal { -namespace { - -// Returns whether current process is browser process, currently we detect it -// by checking whether current has used V8 Lock, but it might be a bad idea. -inline bool IsBrowserProcess() { - return v8::Locker::IsActive(); -} - -} // namespace - v8::Local CallEmitWithArgs(v8::Isolate* isolate, v8::Local obj, ValueVector* args) { // Perform microtask checkpoint after running JavaScript. scoped_ptr script_scope( - IsBrowserProcess() ? nullptr : new blink::WebScopedRunV8Script(isolate)); + Locker::IsBrowserProcess() ? + nullptr : new blink::WebScopedRunV8Script(isolate)); // Use node::MakeCallback to call the callback, and it will also run pending // tasks in Node.js. return node::MakeCallback( diff --git a/atom/common/event_emitter_caller.h b/atom/common/api/event_emitter_caller.h similarity index 92% rename from atom/common/event_emitter_caller.h rename to atom/common/api/event_emitter_caller.h index e8ad50a45378..a2567da9d109 100644 --- a/atom/common/event_emitter_caller.h +++ b/atom/common/api/event_emitter_caller.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_COMMON_EVENT_EMITTER_CALLER_H_ -#define ATOM_COMMON_EVENT_EMITTER_CALLER_H_ +#ifndef ATOM_COMMON_API_EVENT_EMITTER_CALLER_H_ +#define ATOM_COMMON_API_EVENT_EMITTER_CALLER_H_ #include @@ -50,4 +50,4 @@ v8::Local EmitEvent(v8::Isolate* isolate, } // namespace mate -#endif // ATOM_COMMON_EVENT_EMITTER_CALLER_H_ +#endif // ATOM_COMMON_API_EVENT_EMITTER_CALLER_H_ diff --git a/atom/common/api/locker.cc b/atom/common/api/locker.cc new file mode 100644 index 000000000000..fe0b23479a46 --- /dev/null +++ b/atom/common/api/locker.cc @@ -0,0 +1,17 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE.chromium file. + +#include "atom/common/api/locker.h" + +namespace mate { + +Locker::Locker(v8::Isolate* isolate) { + if (IsBrowserProcess()) + locker_.reset(new v8::Locker(isolate)); +} + +Locker::~Locker() { +} + +} // namespace mate diff --git a/atom/common/api/locker.h b/atom/common/api/locker.h new file mode 100644 index 000000000000..201217ff625a --- /dev/null +++ b/atom/common/api/locker.h @@ -0,0 +1,34 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE.chromium file. + +#ifndef ATOM_COMMON_API_LOCKER_H_ +#define ATOM_COMMON_API_LOCKER_H_ + +#include "base/memory/scoped_ptr.h" +#include "v8/include/v8.h" + +namespace mate { + +// Only lock when lockers are used in current thread. +class Locker { + public: + explicit Locker(v8::Isolate* isolate); + ~Locker(); + + // Returns whether current process is browser process, currently we detect it + // by checking whether current has used V8 Lock, but it might be a bad idea. + static inline bool IsBrowserProcess() { return v8::Locker::IsActive(); } + + private: + void* operator new(size_t size); + void operator delete(void*, size_t); + + scoped_ptr locker_; + + DISALLOW_COPY_AND_ASSIGN(Locker); +}; + +} // namespace mate + +#endif // ATOM_COMMON_API_LOCKER_H_ diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index e7dc6af249f8..6e51cda79c49 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -2,13 +2,17 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ + #include +#include "atom/common/api/locker.h" #include "base/bind.h" #include "base/callback.h" #include "native_mate/function_template.h" -#include "native_mate/locker.h" #include "native_mate/scoped_persistent.h" +#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" namespace mate { @@ -25,6 +29,9 @@ struct V8FunctionInvoker(ArgTypes...)> { ArgTypes... raw) { Locker locker(isolate); v8::EscapableHandleScope handle_scope(isolate); + scoped_ptr script_scope( + Locker::IsBrowserProcess() ? + nullptr : new blink::WebScopedRunV8Script(isolate)); v8::Local holder = function->NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); @@ -40,6 +47,9 @@ struct V8FunctionInvoker { ArgTypes... raw) { Locker locker(isolate); v8::HandleScope handle_scope(isolate); + scoped_ptr script_scope( + Locker::IsBrowserProcess() ? + nullptr : new blink::WebScopedRunV8Script(isolate)); v8::Local holder = function->NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); @@ -54,6 +64,9 @@ struct V8FunctionInvoker { ArgTypes... raw) { Locker locker(isolate); v8::HandleScope handle_scope(isolate); + scoped_ptr script_scope( + Locker::IsBrowserProcess() ? + nullptr : new blink::WebScopedRunV8Script(isolate)); v8::Local holder = function->NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); @@ -87,3 +100,5 @@ struct Converter > { }; } // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index b329589552ba..304b6a711a5c 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -7,8 +7,9 @@ #include #include +#include "atom/common/api/event_emitter_caller.h" +#include "atom/common/api/locker.h" #include "atom/common/atom_command_line.h" -#include "atom/common/event_emitter_caller.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "base/command_line.h" #include "base/base_paths.h" @@ -17,7 +18,6 @@ #include "base/path_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_paths.h" -#include "native_mate/locker.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 686481327f5b..1f199ea445c6 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -11,7 +11,7 @@ #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/api/api_messages.h" -#include "atom/common/event_emitter_caller.h" +#include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "atom/renderer/atom_renderer_client.h" diff --git a/filenames.gypi b/filenames.gypi index 977eb1686fd9..b062c6e932b9 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -238,6 +238,10 @@ 'atom/common/api/atom_api_v8_util.cc', 'atom/common/api/atom_bindings.cc', 'atom/common/api/atom_bindings.h', + 'atom/common/api/event_emitter_caller.cc', + 'atom/common/api/event_emitter_caller.h', + 'atom/common/api/locker.cc', + 'atom/common/api/locker.h', 'atom/common/api/object_life_monitor.cc', 'atom/common/api/object_life_monitor.h', 'atom/common/asar/archive.cc', @@ -266,8 +270,6 @@ 'atom/common/crash_reporter/win/crash_service_main.h', 'atom/common/draggable_region.cc', 'atom/common/draggable_region.h', - 'atom/common/event_emitter_caller.cc', - 'atom/common/event_emitter_caller.h', 'atom/common/google_api_key.h', 'atom/common/id_weak_map.cc', 'atom/common/id_weak_map.h', diff --git a/script/lib/config.py b/script/lib/config.py index 144ec87c677b..1298651b7edf 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ - 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' + 'http://github-janky-artifacts.s3.amazonaws.com/libchromiumcontent' LIBCHROMIUMCONTENT_COMMIT = 'dd51a41b42246b0b5159bfad5e327c8cf10bc585' PLATFORM = { diff --git a/vendor/native_mate b/vendor/native_mate index ebcf4c022467..67d9eaa215e8 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit ebcf4c022467a43a5379446e1c031ffd10438b9c +Subproject commit 67d9eaa215e8727d86dc7b1f7a10be8699848f1f From c51f349dfabd03e7cc82d25973faf53157424008 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 21:26:24 +0800 Subject: [PATCH 152/172] Run microtask before handling pending process.nextTick tasks This follows the behavior of Node.js. --- atom/common/api/atom_bindings.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index fa4a88d58437..c748647f48d0 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -98,6 +98,10 @@ void AtomBindings::OnCallNextTick(uv_async_t* handle) { if (tick_info->in_tick()) continue; + if (tick_info->length() == 0) { + env->isolate()->RunMicrotasks(); + } + if (tick_info->length() == 0) { tick_info->set_index(0); continue; From 0bf5effe58b06732da5e2d2a48f2a5a4a8fcda6f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 7 Aug 2015 22:04:59 +0800 Subject: [PATCH 153/172] Bump v0.30.3 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index dc53c6b9575d..620464e22574 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.30.2', + 'version%': '0.30.3', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index aad2ec56db68..23af6a804901 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.30.2 + 0.30.3 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 68eff5577f08..2379d294a35c 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,30,2,0 - PRODUCTVERSION 0,30,2,0 + FILEVERSION 0,30,3,0 + PRODUCTVERSION 0,30,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.30.2" + VALUE "FileVersion", "0.30.3" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.30.2" + VALUE "ProductVersion", "0.30.3" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 5612bd6463fc..761c7463bb08 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 30 -#define ATOM_PATCH_VERSION 2 +#define ATOM_PATCH_VERSION 3 #define ATOM_VERSION_IS_RELEASE 1 From de441916d6e0e180a54f598ce0be3f8d7b5173e1 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Sat, 8 Aug 2015 23:25:27 +0300 Subject: [PATCH 154/172] Add a comment to build instructions about cpplint I added a mention of `cpplint.py` in the build instructions. The reason, is because it's easy to miss it's existence. Even if you noticed it's mentioned in `coding-style.md` you might mistakenly think that `test.py` runs it). --- docs/development/build-instructions-linux.md | 12 ++++++++++-- docs/development/build-instructions-mac.md | 8 ++++++++ docs/development/build-instructions-windows.md | 8 ++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/development/build-instructions-linux.md b/docs/development/build-instructions-linux.md index 3fe3b53c210f..6f4ce4e1468a 100644 --- a/docs/development/build-instructions-linux.md +++ b/docs/development/build-instructions-linux.md @@ -106,8 +106,8 @@ Make sure you have installed all the build dependencies. ### error while loading shared libraries: libtinfo.so.5 -Prebulit `clang` will try to link to `libtinfo.so.5`. Depending on the host architecture, -symlink to appropirate `libncurses` +Prebulit `clang` will try to link to `libtinfo.so.5`. Depending on the host +architecture, symlink to appropriate `libncurses` ```bash $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5 @@ -115,6 +115,14 @@ $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5 ## Tests +Test your changes confirm to the project coding style using: + +```bash +$ ./script/cpplint.py +``` + +Test functionality using: + ```bash $ ./script/test.py ``` diff --git a/docs/development/build-instructions-mac.md b/docs/development/build-instructions-mac.md index b0980a231250..af59f996f4a5 100644 --- a/docs/development/build-instructions-mac.md +++ b/docs/development/build-instructions-mac.md @@ -51,6 +51,14 @@ support 32bit OS X in future. ## Tests +Test your changes confirm to the project coding style using: + +```bash +$ ./script/cpplint.py +``` + +Test functionality using: + ```bash $ ./script/test.py ``` diff --git a/docs/development/build-instructions-windows.md b/docs/development/build-instructions-windows.md index 7f32b4645eb8..061011b5a1a4 100644 --- a/docs/development/build-instructions-windows.md +++ b/docs/development/build-instructions-windows.md @@ -67,6 +67,14 @@ The other building steps are exactly the same. ## Tests +Test your changes confirm to the project coding style using: + +```powershell +python script\cpplint.py +``` + +Test functionality using: + ```powershell python script\test.py ``` From 70be04a2d3fba1fabc478aadf17b4137f34559d4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 11:28:43 +0800 Subject: [PATCH 155/172] Upload headers with new filenames --- script/upload-node-headers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script/upload-node-headers.py b/script/upload-node-headers.py index 38cb2f7e16f5..230b08ed5ac7 100755 --- a/script/upload-node-headers.py +++ b/script/upload-node-headers.py @@ -40,11 +40,15 @@ def main(): args = parse_args() node_headers_dir = os.path.join(DIST_DIR, 'node-{0}'.format(args.version)) iojs_headers_dir = os.path.join(DIST_DIR, 'iojs-{0}'.format(args.version)) + iojs2_headers_dir = os.path.join(DIST_DIR, + 'iojs-{0}-headers'.format(args.version)) copy_headers(node_headers_dir) create_header_tarball(node_headers_dir) copy_headers(iojs_headers_dir) create_header_tarball(iojs_headers_dir) + copy_headers(iojs2_headers_dir) + create_header_tarball(iojs2_headers_dir) # Upload node's headers to S3. bucket, access_key, secret_key = s3_config() From 52d07eb30f3572891b7765b0f5d9d607aec70607 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 11:42:14 +0800 Subject: [PATCH 156/172] Update checksums for new filenames --- script/upload-checksums.py | 1 + 1 file changed, 1 insertion(+) diff --git a/script/upload-checksums.py b/script/upload-checksums.py index c71425126363..776a5debdb64 100755 --- a/script/upload-checksums.py +++ b/script/upload-checksums.py @@ -40,6 +40,7 @@ def get_files_list(version): return [ 'node-{0}.tar.gz'.format(version), 'iojs-{0}.tar.gz'.format(version), + 'iojs-{0}-headers.tar.gz'.format(version), 'node.lib', 'x64/node.lib', 'win-x86/iojs.lib', From 0a49dcc623833d34e8a65d4c84cbf1df0cb8e858 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 11:56:42 +0800 Subject: [PATCH 157/172] Delay the call of element resize callback to next tick --- atom/renderer/guest_view_container.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/atom/renderer/guest_view_container.cc b/atom/renderer/guest_view_container.cc index 638df2177e48..7643f72b0e5b 100644 --- a/atom/renderer/guest_view_container.cc +++ b/atom/renderer/guest_view_container.cc @@ -7,6 +7,7 @@ #include #include "base/lazy_instance.h" +#include "ui/gfx/geometry/size.h" namespace atom { @@ -51,7 +52,9 @@ void GuestViewContainer::DidResizeElement(const gfx::Size& old_size, if (element_resize_callback_.is_null()) return; - element_resize_callback_.Run(old_size, new_size); + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(element_resize_callback_, old_size, new_size)); } } // namespace atom From a3f3a35fd17349ce2d0e3c3b213e6d8f10855c99 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 12:18:00 +0800 Subject: [PATCH 158/172] mac: Don't emit "clicked" event if there is menu attached --- atom/browser/ui/tray_icon_cocoa.mm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 055ac12c4046..3ac865cce5ab 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -207,23 +207,26 @@ const CGFloat kVerticalTitleMargin = 2; } inMouseEventSequence_ = NO; - // Single click - if (event.clickCount == 1) { - if (menuController_) { - [statusItem_ popUpStatusItemMenu:[menuController_ menu]]; - } + // Show menu when single clicked on the icon. + if (event.clickCount == 1 && menuController_) + [statusItem_ popUpStatusItemMenu:[menuController_ menu]]; + // Don't emit click events when menu is showing. + if (menuController_) + return; + + // Single click event. + if (event.clickCount == 1) trayIcon_->NotifyClicked( [self getBoundsFromEvent:event], ui::EventFlagsFromModifiers([event modifierFlags])); - } - // Double click - if (event.clickCount == 2 && !menuController_) { + // Double click event. + if (event.clickCount == 2) trayIcon_->NotifyDoubleClicked( [self getBoundsFromEvent:event], ui::EventFlagsFromModifiers([event modifierFlags])); - } + [self setNeedsDisplay:YES]; } From 4b9ff309ece31507862a5279d545a8cb1b2b43b2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 12:39:05 +0800 Subject: [PATCH 159/172] Add our own MenuModel class --- atom/browser/api/atom_api_menu.cc | 2 +- atom/browser/api/atom_api_menu.h | 14 +++--- atom/browser/ui/atom_menu_model.cc | 22 +++++++++ atom/browser/ui/atom_menu_model.h | 47 +++++++++++++++++++ atom/browser/ui/cocoa/atom_menu_controller.mm | 5 +- filenames.gypi | 2 + 6 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 atom/browser/ui/atom_menu_model.cc create mode 100644 atom/browser/ui/atom_menu_model.h diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index 915e152b3a68..356a4d4ce494 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -20,7 +20,7 @@ namespace atom { namespace api { Menu::Menu() - : model_(new ui::SimpleMenuModel(this)), + : model_(new AtomMenuModel(this)), parent_(NULL) { } diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 0c2743878f78..33aafbc45d3b 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -8,9 +8,9 @@ #include #include "atom/browser/api/atom_api_window.h" +#include "atom/browser/ui/atom_menu_model.h" #include "base/callback.h" #include "base/memory/scoped_ptr.h" -#include "ui/base/models/simple_menu_model.h" #include "native_mate/wrappable.h" namespace atom { @@ -18,7 +18,7 @@ namespace atom { namespace api { class Menu : public mate::Wrappable, - public ui::SimpleMenuModel::Delegate { + public AtomMenuModel::Delegate { public: static mate::Wrappable* Create(); @@ -33,7 +33,7 @@ class Menu : public mate::Wrappable, static void SendActionToFirstResponder(const std::string& action); #endif - ui::SimpleMenuModel* model() const { return model_.get(); } + AtomMenuModel* model() const { return model_.get(); } protected: Menu(); @@ -42,7 +42,7 @@ class Menu : public mate::Wrappable, // mate::Wrappable: void AfterInit(v8::Isolate* isolate) override; - // ui::SimpleMenuModel::Delegate implementations: + // ui::SimpleMenuModel::Delegate: bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; bool IsCommandIdVisible(int command_id) const override; @@ -54,7 +54,7 @@ class Menu : public mate::Wrappable, virtual void Popup(Window* window) = 0; virtual void PopupAt(Window* window, int x, int y) = 0; - scoped_ptr model_; + scoped_ptr model_; Menu* parent_; private: @@ -102,9 +102,9 @@ class Menu : public mate::Wrappable, namespace mate { template<> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, - ui::SimpleMenuModel** out) { + atom::AtomMenuModel** out) { // null would be tranfered to NULL. if (val->IsNull()) { *out = nullptr; diff --git a/atom/browser/ui/atom_menu_model.cc b/atom/browser/ui/atom_menu_model.cc new file mode 100644 index 000000000000..7d2d5e1b6a1f --- /dev/null +++ b/atom/browser/ui/atom_menu_model.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/atom_menu_model.h" + +namespace atom { + +AtomMenuModel::AtomMenuModel(Delegate* delegate) + : ui::SimpleMenuModel(delegate), + delegate_(delegate) { +} + +AtomMenuModel::~AtomMenuModel() { +} + +void AtomMenuModel::MenuClosed() { + ui::SimpleMenuModel::MenuClosed(); + FOR_EACH_OBSERVER(Observer, observers_, MenuClosed()); +} + +} // namespace atom diff --git a/atom/browser/ui/atom_menu_model.h b/atom/browser/ui/atom_menu_model.h new file mode 100644 index 000000000000..42e0e5dbc53a --- /dev/null +++ b/atom/browser/ui/atom_menu_model.h @@ -0,0 +1,47 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_ATOM_MENU_MODEL_H_ +#define ATOM_BROWSER_UI_ATOM_MENU_MODEL_H_ + +#include "base/observer_list.h" +#include "ui/base/models/simple_menu_model.h" + +namespace atom { + +class AtomMenuModel : public ui::SimpleMenuModel { + public: + class Delegate : public ui::SimpleMenuModel::Delegate { + public: + virtual ~Delegate() {} + }; + + class Observer { + public: + virtual ~Observer() {} + + // Notifies the menu has been closed. + virtual void MenuClosed() {} + }; + + explicit AtomMenuModel(Delegate* delegate); + virtual ~AtomMenuModel(); + + void AddObserver(Observer* obs) { observers_.AddObserver(obs); } + void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); } + + // ui::SimpleMenuModel: + void MenuClosed() override; + + private: + Delegate* delegate_; // weak ref. + + ObserverList observers_; + + DISALLOW_COPY_AND_ASSIGN(AtomMenuModel); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_ATOM_MENU_MODEL_H_ diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 962dd6b0ad36..d799a9f9b64d 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -5,12 +5,12 @@ #import "atom/browser/ui/cocoa/atom_menu_controller.h" +#include "atom/browser/ui/atom_menu_model.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/accelerators/platform_accelerator_cocoa.h" #include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/models/simple_menu_model.h" #include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/gfx/image/image.h" @@ -120,8 +120,7 @@ [item setTarget:nil]; [item setAction:nil]; ui::MenuModel* submenuModel = model->GetSubmenuModelAt(index); - NSMenu* submenu = - [self menuFromModel:(ui::SimpleMenuModel*)submenuModel]; + NSMenu* submenu = [self menuFromModel:submenuModel]; [submenu setTitle:[item title]]; [item setSubmenu:submenu]; diff --git a/filenames.gypi b/filenames.gypi index b062c6e932b9..40af1ebb1fe7 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -166,6 +166,8 @@ 'atom/browser/ui/accelerator_util.h', 'atom/browser/ui/accelerator_util_mac.mm', 'atom/browser/ui/accelerator_util_views.cc', + 'atom/browser/ui/atom_menu_model.cc', + 'atom/browser/ui/atom_menu_model.h', 'atom/browser/ui/cocoa/atom_menu_controller.h', 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/event_processing_window.h', From 58dee04d5c2317cd9c597b3e0b4b2a885512ef36 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 12:48:22 +0800 Subject: [PATCH 160/172] mac: Redraw icon when menu is closed --- atom/browser/ui/tray_icon_cocoa.h | 11 ++++++++++- atom/browser/ui/tray_icon_cocoa.mm | 14 +++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.h b/atom/browser/ui/tray_icon_cocoa.h index 9aa801ec5ead..db53adcbe85d 100644 --- a/atom/browser/ui/tray_icon_cocoa.h +++ b/atom/browser/ui/tray_icon_cocoa.h @@ -9,6 +9,7 @@ #include +#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/tray_icon.h" #include "base/mac/scoped_nsobject.h" @@ -17,7 +18,8 @@ namespace atom { -class TrayIconCocoa : public TrayIcon { +class TrayIconCocoa : public TrayIcon, + public AtomMenuModel::Observer { public: TrayIconCocoa(); virtual ~TrayIconCocoa(); @@ -30,6 +32,10 @@ class TrayIconCocoa : public TrayIcon { void PopContextMenu(const gfx::Point& pos) override; void SetContextMenu(ui::SimpleMenuModel* menu_model) override; + protected: + // AtomMenuModel::Observer: + void MenuClosed() override; + private: // Atom custom view for NSStatusItem. base::scoped_nsobject status_item_view_; @@ -37,6 +43,9 @@ class TrayIconCocoa : public TrayIcon { // Status menu shown when right-clicking the system icon. base::scoped_nsobject menu_; + // Used for unregistering observer. + AtomMenuModel* menu_model_; // weak ref. + DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa); }; diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 3ac865cce5ab..7c2214e06399 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -281,11 +281,13 @@ const CGFloat kVerticalTitleMargin = 2; namespace atom { -TrayIconCocoa::TrayIconCocoa() { +TrayIconCocoa::TrayIconCocoa() : menu_model_(nullptr) { } TrayIconCocoa::~TrayIconCocoa() { [status_item_view_ removeItem]; + if (menu_model_) + menu_model_->RemoveObserver(this); } void TrayIconCocoa::SetImage(const gfx::Image& image) { @@ -319,10 +321,20 @@ void TrayIconCocoa::PopContextMenu(const gfx::Point& pos) { } void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) { + // Substribe to MenuClosed event. + if (menu_model_) + menu_model_->RemoveObserver(this); + static_cast(menu_model)->AddObserver(this); + + // Create native menu. menu_.reset([[AtomMenuController alloc] initWithModel:menu_model]); [status_item_view_ setMenuController:menu_.get()]; } +void TrayIconCocoa::MenuClosed() { + [status_item_view_ setNeedsDisplay:YES]; +} + // static TrayIcon* TrayIcon::Create() { return new TrayIconCocoa; From 225140bd64e07b935d498335732b468b24c56c8c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 12:52:55 +0800 Subject: [PATCH 161/172] win: Don't emit right-clicked event when there is menu attached --- atom/browser/ui/win/notify_icon.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 962dc871b5b6..ebc958384363 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -86,8 +86,10 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, NotifyClicked(gfx::Rect(rect), modifiers); return; } else if (!double_button_click) { // single right click - NotifyRightClicked(gfx::Rect(rect), modifiers); - PopContextMenu(cursor_pos); + if (menu_model_) + PopContextMenu(cursor_pos); + else + NotifyRightClicked(gfx::Rect(rect), modifiers); } } From 33eadad139136bce7f8c9fe4f152f8576aa7e69b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 13:00:15 +0800 Subject: [PATCH 162/172] popContextMenu => popUpContextMenu --- atom/browser/api/atom_api_tray.cc | 6 +++--- atom/browser/api/atom_api_tray.h | 2 +- atom/browser/api/lib/tray.coffee | 4 ++++ atom/browser/ui/tray_icon.cc | 2 +- atom/browser/ui/tray_icon.h | 2 +- atom/browser/ui/tray_icon_cocoa.h | 2 +- atom/browser/ui/tray_icon_cocoa.mm | 6 +++--- atom/browser/ui/win/notify_icon.cc | 4 ++-- atom/browser/ui/win/notify_icon.h | 2 +- docs/api/tray.md | 4 ++-- 10 files changed, 19 insertions(+), 15 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 0f07737da2bf..1382f015a63b 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -120,10 +120,10 @@ void Tray::DisplayBalloon(mate::Arguments* args, tray_icon_->DisplayBalloon(icon, title, content); } -void Tray::PopContextMenu(mate::Arguments* args) { +void Tray::PopUpContextMenu(mate::Arguments* args) { gfx::Point pos; args->GetNext(&pos); - tray_icon_->PopContextMenu(pos); + tray_icon_->PopUpContextMenu(pos); } void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) { @@ -151,7 +151,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate, .SetMethod("setTitle", &Tray::SetTitle) .SetMethod("setHighlightMode", &Tray::SetHighlightMode) .SetMethod("displayBalloon", &Tray::DisplayBalloon) - .SetMethod("popContextMenu", &Tray::PopContextMenu) + .SetMethod("popUpContextMenu", &Tray::PopUpContextMenu) .SetMethod("_setContextMenu", &Tray::SetContextMenu); } diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 02f7418fe41d..dc9302597cf3 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -60,7 +60,7 @@ class Tray : public mate::EventEmitter, void SetTitle(mate::Arguments* args, const std::string& title); void SetHighlightMode(mate::Arguments* args, bool highlight); void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options); - void PopContextMenu(mate::Arguments* args); + void PopUpContextMenu(mate::Arguments* args); void SetContextMenu(mate::Arguments* args, Menu* menu); private: diff --git a/atom/browser/api/lib/tray.coffee b/atom/browser/api/lib/tray.coffee index 7d158a9a0104..1c225ddd403c 100644 --- a/atom/browser/api/lib/tray.coffee +++ b/atom/browser/api/lib/tray.coffee @@ -3,8 +3,12 @@ bindings = process.atomBinding 'tray' Tray = bindings.Tray Tray::__proto__ = EventEmitter.prototype + Tray::setContextMenu = (menu) -> @_setContextMenu menu @menu = menu # Keep a strong reference of menu. +# Keep compatibility with old APIs. +Tray::popContextMenu = Tray::popUpContextMenu + module.exports = Tray diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index cc19be6d8d86..12c6be2ea74e 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -26,7 +26,7 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon, const base::string16& contents) { } -void TrayIcon::PopContextMenu(const gfx::Point& pos) { +void TrayIcon::PopUpContextMenu(const gfx::Point& pos) { } void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 6d917a53467c..55f1c41d19d7 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -47,7 +47,7 @@ class TrayIcon { const base::string16& title, const base::string16& contents); - virtual void PopContextMenu(const gfx::Point& pos); + virtual void PopUpContextMenu(const gfx::Point& pos); // Set the context menu for this icon. virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0; diff --git a/atom/browser/ui/tray_icon_cocoa.h b/atom/browser/ui/tray_icon_cocoa.h index db53adcbe85d..7781c93a1c03 100644 --- a/atom/browser/ui/tray_icon_cocoa.h +++ b/atom/browser/ui/tray_icon_cocoa.h @@ -29,7 +29,7 @@ class TrayIconCocoa : public TrayIcon, void SetToolTip(const std::string& tool_tip) override; void SetTitle(const std::string& title) override; void SetHighlightMode(bool highlight) override; - void PopContextMenu(const gfx::Point& pos) override; + void PopUpContextMenu(const gfx::Point& pos) override; void SetContextMenu(ui::SimpleMenuModel* menu_model) override; protected: diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 7c2214e06399..d69fa8636b4f 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -230,7 +230,7 @@ const CGFloat kVerticalTitleMargin = 2; [self setNeedsDisplay:YES]; } -- (void)popContextMenu { +- (void)popUpContextMenu { if (menuController_ && ![menuController_ isMenuOpen]) { // Redraw the dray icon to show highlight if it is enabled. [self setNeedsDisplay:YES]; @@ -316,8 +316,8 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) { [status_item_view_ setHighlight:highlight]; } -void TrayIconCocoa::PopContextMenu(const gfx::Point& pos) { - [status_item_view_ popContextMenu]; +void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos) { + [status_item_view_ popUpContextMenu]; } void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) { diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index ebc958384363..c4c0fe9141e3 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -87,7 +87,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, return; } else if (!double_button_click) { // single right click if (menu_model_) - PopContextMenu(cursor_pos); + PopUpContextMenu(cursor_pos); else NotifyRightClicked(gfx::Rect(rect), modifiers); } @@ -163,7 +163,7 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, LOG(WARNING) << "Unable to create status tray balloon."; } -void NotifyIcon::PopContextMenu(const gfx::Point& pos) { +void NotifyIcon::PopUpContextMenu(const gfx::Point& pos) { // Returns if context menu isn't set. if (!menu_model_) return; diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index a28a00ff0d6a..136186b689b9 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -52,7 +52,7 @@ class NotifyIcon : public TrayIcon { void DisplayBalloon(const gfx::Image& icon, const base::string16& title, const base::string16& contents) override; - void PopContextMenu(const gfx::Point& pos) override; + void PopUpContextMenu(const gfx::Point& pos) override; void SetContextMenu(ui::SimpleMenuModel* menu_model) override; private: diff --git a/docs/api/tray.md b/docs/api/tray.md index 3d3ebc280f5a..a67772746128 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -60,7 +60,7 @@ Creates a new tray icon associated with the `image`. Emitted when the tray icon is clicked. -__Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newer. +__Note:__ The `bounds` payload is only implemented on OS X and Windows. ### Event: 'right-clicked' @@ -173,7 +173,7 @@ Displays a tray balloon. __Note:__ This is only implemented on Windows. -### Tray.popContextMenu([position]) +### Tray.popUpContextMenu([position]) * `position` Object - The pop position * `x` Integer From c2959792704a79e057e65c0e0dad1d20be39c8e5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 15:02:16 +0800 Subject: [PATCH 163/172] BrowserContext::GetRequestContext can only be called on UI thread --- atom/browser/api/atom_api_cookies.cc | 23 +++++++++++------------ atom/browser/api/atom_api_cookies.h | 24 ++++++++++++++++++------ atom/browser/api/atom_api_session.cc | 11 ++++++----- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 040efe1c360b..4d87d9b5b0ef 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -9,6 +9,7 @@ #include "atom/common/native_mate_converters/value_converter.h" #include "base/bind.h" #include "base/time/time.h" +#include "base/values.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "native_mate/dictionary.h" @@ -179,8 +180,8 @@ namespace atom { namespace api { -Cookies::Cookies(content::BrowserContext* browser_context) : - browser_context_(browser_context) { +Cookies::Cookies(content::BrowserContext* browser_context) + : request_context_getter_(browser_context->GetRequestContext()) { } Cookies::~Cookies() { @@ -198,11 +199,9 @@ void Cookies::Get(const base::DictionaryValue& options, void Cookies::GetCookiesOnIOThread(scoped_ptr filter, const CookiesCallback& callback) { - net::CookieStore* cookie_store = browser_context_->GetRequestContext() - ->GetURLRequestContext()->cookie_store(); std::string url; filter->GetString("url", &url); - if (!GetCookieListFromStore(cookie_store, url, + if (!GetCookieListFromStore(GetCookieStore(), url, base::Bind(&Cookies::OnGetCookies, base::Unretained(this), Passed(&filter), callback))) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, @@ -245,9 +244,7 @@ void Cookies::Remove(const mate::Dictionary& details, void Cookies::RemoveCookiesOnIOThread(const GURL& url, const std::string& name, const CookiesCallback& callback) { - net::CookieStore* cookie_store = browser_context_->GetRequestContext() - ->GetURLRequestContext()->cookie_store(); - cookie_store->DeleteCookieAsync(url, name, + GetCookieStore()->DeleteCookieAsync(url, name, base::Bind(&Cookies::OnRemoveCookies, base::Unretained(this), callback)); } @@ -286,8 +283,6 @@ void Cookies::SetCookiesOnIOThread(scoped_ptr details, const GURL& url, const CookiesCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::CookieStore* cookie_store = browser_context_->GetRequestContext() - ->GetURLRequestContext()->cookie_store(); std::string name, value, domain, path; bool secure = false; @@ -308,7 +303,7 @@ void Cookies::SetCookiesOnIOThread(scoped_ptr details, base::Time::FromDoubleT(expiration_date); } - cookie_store->GetCookieMonster()->SetCookieWithDetailsAsync( + GetCookieStore()->GetCookieMonster()->SetCookieWithDetailsAsync( url, name, value, @@ -337,6 +332,10 @@ mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder( .SetMethod("set", &Cookies::Set); } +net::CookieStore* Cookies::GetCookieStore() { + return request_context_getter_->GetURLRequestContext()->cookie_store(); +} + // static mate::Handle Cookies::Create( v8::Isolate* isolate, @@ -346,4 +345,4 @@ mate::Handle Cookies::Create( } // namespace api -} // namespace atom +} // namespace atotContext diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h index 61357f05d75d..12cf4a220979 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -8,17 +8,27 @@ #include #include "base/callback.h" -#include "base/values.h" #include "native_mate/wrappable.h" #include "native_mate/handle.h" -#include "native_mate/dictionary.h" - #include "net/cookies/canonical_cookie.h" +namespace base { +class DictionaryValue; +} + namespace content { class BrowserContext; } +namespace mate { +class Dictionary; +} + +namespace net { +class CookieStore; +class URLRequestContextGetter; +} + namespace atom { namespace api { @@ -60,13 +70,15 @@ class Cookies : public mate::Wrappable { void OnSetCookies(const CookiesCallback& callback, bool set_success); - - // mate::Wrappable implementations: + // mate::Wrappable: mate::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate) override; private: - content::BrowserContext* browser_context_; + // Must be called on IO thread. + net::CookieStore* GetCookieStore(); + + scoped_refptr request_context_getter_; DISALLOW_COPY_AND_ASSIGN(Cookies); }; diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index b8b1434dd70d..9961d6cc6601 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -19,6 +19,7 @@ #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" +#include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/base/load_flags.h" #include "net/disk_cache/disk_cache.h" @@ -181,10 +182,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr, } } -void ClearHttpCacheInIO(content::BrowserContext* browser_context, - const net::CompletionCallback& callback) { - auto request_context = - browser_context->GetRequestContext()->GetURLRequestContext(); +void ClearHttpCacheInIO( + const scoped_refptr& context_getter, + const net::CompletionCallback& callback) { + auto request_context = context_getter->GetURLRequestContext(); auto http_cache = request_context->http_transaction_factory()->GetCache(); if (!http_cache) RunCallbackInUI(callback, net::ERR_FAILED); @@ -226,7 +227,7 @@ void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { void Session::ClearCache(const net::CompletionCallback& callback) { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&ClearHttpCacheInIO, - base::Unretained(browser_context_), + make_scoped_refptr(browser_context_->GetRequestContext()), callback)); } From 0644129fbe46580539423d21a004d2241e527732 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 15:28:18 +0800 Subject: [PATCH 164/172] Pass net::URLRequestContextGetter in scoped_refptr --- atom/browser/api/atom_api_protocol.cc | 38 ++++++++++------------- atom/browser/api/atom_api_protocol.h | 8 +++-- atom/browser/api/atom_api_session.h | 8 ++--- atom/browser/net/adapter_request_job.cc | 2 +- atom/browser/net/adapter_request_job.h | 2 +- atom/browser/net/url_request_fetch_job.cc | 4 +-- atom/browser/net/url_request_fetch_job.h | 2 +- 7 files changed, 31 insertions(+), 33 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 1241a95a718f..fdc5ba422bd3 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -35,23 +35,6 @@ struct Converter { } }; -template<> -struct Converter { - static bool FromV8(v8::Isolate* isolate, v8::Local val, - net::URLRequestContextGetter** out) { - if (val->IsNull()) { - *out = nullptr; - return true; - } - - atom::api::Session* session; - if (!Converter::FromV8(isolate, val, &session)) - return false; - *out = session->browser_context()->GetRequestContext(); - return true; - } -}; - } // namespace mate namespace atom { @@ -141,16 +124,27 @@ class CustomProtocolRequestJob : public AdapterRequestJob { } else if (name == "RequestHttpJob") { GURL url; std::string method, referrer; - net::URLRequestContextGetter* getter = - registry_->browser_context()->GetRequestContext(); dict.Get("url", &url); dict.Get("method", &method); dict.Get("referrer", &referrer); - dict.Get("session", &getter); + + v8::Local value; + mate::Handle session; + scoped_refptr request_context_getter; + // "session" null -> pass nullptr; + // "session" a Session object -> use passed session. + // "session" undefined -> use current session; + if (dict.Get("session", &session)) + request_context_getter = + session->browser_context()->GetRequestContext(); + else if (dict.Get("session", &value) && value->IsNull()) + request_context_getter = nullptr; + else + request_context_getter = registry_->request_context_getter(); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&AdapterRequestJob::CreateHttpJobAndStart, GetWeakPtr(), - base::Unretained(getter), url, method, referrer)); + request_context_getter, url, method, referrer)); return; } } @@ -237,7 +231,7 @@ std::string ConvertErrorCode(int error_code) { } // namespace Protocol::Protocol(AtomBrowserContext* browser_context) - : browser_context_(browser_context), + : request_context_getter_(browser_context->GetRequestContext()), job_factory_(browser_context->job_factory()) { CHECK(job_factory_); } diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index b4d56018baf3..4dec17a74340 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -16,6 +16,7 @@ namespace net { class URLRequest; +class URLRequestContextGetter; } namespace atom { @@ -46,7 +47,9 @@ class Protocol : public mate::EventEmitter { JsProtocolHandler GetProtocolHandler(const std::string& scheme); - AtomBrowserContext* browser_context() const { return browser_context_; } + net::URLRequestContextGetter* request_context_getter() { + return request_context_getter_.get(); + } protected: explicit Protocol(AtomBrowserContext* browser_context); @@ -94,7 +97,8 @@ class Protocol : public mate::EventEmitter { const JsProtocolHandler& handler); int UninterceptProtocolInIO(const std::string& scheme); - AtomBrowserContext* browser_context_; + scoped_refptr request_context_getter_; + AtomURLRequestJobFactory* job_factory_; ProtocolHandlersMap protocol_handlers_; diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index bd12b7589914..b353c61c2109 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -13,14 +13,14 @@ class GURL; -namespace mate { -class Arguments; -} - namespace base { class FilePath; } +namespace mate { +class Arguments; +} + namespace atom { class AtomBrowserContext; diff --git a/atom/browser/net/adapter_request_job.cc b/atom/browser/net/adapter_request_job.cc index 5c41c6f65aac..ca7dcf2e566b 100644 --- a/atom/browser/net/adapter_request_job.cc +++ b/atom/browser/net/adapter_request_job.cc @@ -119,7 +119,7 @@ void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) { } void AdapterRequestJob::CreateHttpJobAndStart( - net::URLRequestContextGetter* request_context_getter, + scoped_refptr request_context_getter, const GURL& url, const std::string& method, const std::string& referrer) { diff --git a/atom/browser/net/adapter_request_job.h b/atom/browser/net/adapter_request_job.h index b1d28b1446c1..afb9d5f55d07 100644 --- a/atom/browser/net/adapter_request_job.h +++ b/atom/browser/net/adapter_request_job.h @@ -65,7 +65,7 @@ class AdapterRequestJob : public net::URLRequestJob { scoped_refptr data); void CreateFileJobAndStart(const base::FilePath& path); void CreateHttpJobAndStart( - net::URLRequestContextGetter* request_context_getter, + scoped_refptr request_context_getter, const GURL& url, const std::string& method, const std::string& referrer); diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index abad38d7f4d5..ee4c67b371ee 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -75,7 +75,7 @@ class ResponsePiper : public net::URLFetcherResponseWriter { } // namespace URLRequestFetchJob::URLRequestFetchJob( - net::URLRequestContextGetter* request_context_getter, + scoped_refptr request_context_getter, net::URLRequest* request, net::NetworkDelegate* network_delegate, const GURL& url, @@ -93,7 +93,7 @@ URLRequestFetchJob::URLRequestFetchJob( fetcher_.reset(net::URLFetcher::Create(url, request_type, this)); // Use request context if provided else create one. if (request_context_getter) - fetcher_->SetRequestContext(request_context_getter); + fetcher_->SetRequestContext(request_context_getter.get()); else fetcher_->SetRequestContext(GetRequestContext()); diff --git a/atom/browser/net/url_request_fetch_job.h b/atom/browser/net/url_request_fetch_job.h index 228af7904fe9..a14e8dd1aae3 100644 --- a/atom/browser/net/url_request_fetch_job.h +++ b/atom/browser/net/url_request_fetch_job.h @@ -18,7 +18,7 @@ class AtomBrowserContext; class URLRequestFetchJob : public net::URLRequestJob, public net::URLFetcherDelegate { public: - URLRequestFetchJob(net::URLRequestContextGetter* request_context_getter, + URLRequestFetchJob(scoped_refptr context_getter, net::URLRequest* request, net::NetworkDelegate* network_delegate, const GURL& url, From 3379641fe211b37e7264c2e56de5a9f7c3f57c84 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 15:31:29 +0800 Subject: [PATCH 165/172] Force request context to initialize beforing incepting protocol --- atom/browser/api/atom_api_protocol.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index fdc5ba422bd3..d7d308b306ed 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -355,6 +355,10 @@ int Protocol::InterceptProtocolInIO(const std::string& scheme, const JsProtocolHandler& handler) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + // Force the request context to initialize, otherwise we might have nothing + // to intercept. + request_context_getter_->GetURLRequestContext(); + if (!job_factory_->HasProtocolHandler(scheme)) return ERR_NO_SCHEME; From 140ba2858afd32e1ee647bb6e39879cb7000a3e5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 15:36:47 +0800 Subject: [PATCH 166/172] Fix cpplint warnings --- atom/browser/api/atom_api_cookies.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 4d87d9b5b0ef..bf56a8dc13bd 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -345,4 +345,4 @@ mate::Handle Cookies::Create( } // namespace api -} // namespace atotContext +} // namespace atom From b4e836bf2ee20d4675f548c70754cf12db8fb7c8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Aug 2015 15:47:49 +0800 Subject: [PATCH 167/172] Bump v0.30.4 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index 620464e22574..d24f193ac2db 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.30.3', + 'version%': '0.30.4', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 23af6a804901..a8c009acaff5 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.30.3 + 0.30.4 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 2379d294a35c..b22d3d88f6c4 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,30,3,0 - PRODUCTVERSION 0,30,3,0 + FILEVERSION 0,30,4,0 + PRODUCTVERSION 0,30,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.30.3" + VALUE "FileVersion", "0.30.4" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.30.3" + VALUE "ProductVersion", "0.30.4" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 761c7463bb08..405a104a76f7 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 30 -#define ATOM_PATCH_VERSION 3 +#define ATOM_PATCH_VERSION 4 #define ATOM_VERSION_IS_RELEASE 1 From 8f32f9f5cb20c19101a25c624b66f180dd214034 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Aug 2015 09:45:45 -0700 Subject: [PATCH 168/172] Open Code of Conduct -> Contributor Covenant --- CONTRIBUTING.md | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c86a6d1c2d21..61a8e474099a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,8 +2,8 @@ :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: -This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code. -[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Electron/opensource@github.com +This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0). +By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. The following is a set of guidelines for contributing to Electron. These are just guidelines, not rules, use your best judgment and feel free to diff --git a/README.md b/README.md index 764a6abfe9c3..8b7d36046a76 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ editor](https://github.com/atom/atom). Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important announcements. -This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code. -[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Electron/opensource@github.com +This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0). +By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. ## Downloads From 6f25996fa1e4fd8b6db9eb995bb9ebf6d76dd8af Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Sun, 16 Aug 2015 23:20:09 +0300 Subject: [PATCH 169/172] Fixed typo --- atom/browser/lib/init.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index e61323bfdcc0..069eed8d1b53 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -38,7 +38,7 @@ process.on 'uncaughtException', (error) -> # Show error in GUI. stack = error.stack ? "#{error.name}: #{error.message}" message = "Uncaught Exception:\n#{stack}" - require('dialog').showErrorBox 'A JavaScript error occured in the main process', message + require('dialog').showErrorBox 'A JavaScript error occurred in the main process', message # Emit 'exit' event on quit. app = require 'app' From 763dcc545dc7b0d3abeda94fcb1a51be3f82e475 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 17 Aug 2015 13:20:36 +0800 Subject: [PATCH 170/172] Correct generation of GUID on Windows. --- atom/browser/ui/win/notify_icon.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 962dc871b5b6..48d0f875bcd0 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -39,6 +39,16 @@ NotifyIcon::NotifyIcon(NotifyIconHost* host, base::MD5Sum(explicit_app_id, sizeof(wchar_t) * wcslen(explicit_app_id), reinterpret_cast(&tray_app_id_hash_)); + + // Set the GUID to version 4 as described in RFC 4122, section 4.4. + // The format of GUID version 4 must be like + // xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, where y is one of [8, 9, A, B]. + tray_app_id_hash_.Data3 &= 0x0fff; + tray_app_id_hash_.Data3 |= 0x4000; + + // Set y to one of [8, 9, A, B]. + tray_app_id_hash_.Data4[0] = 1; + has_tray_app_id_hash_ = true; CoTaskMemFree(explicit_app_id); } From acffc713e09559955d9f9f33d1d7e3bfde3d64fc Mon Sep 17 00:00:00 2001 From: Petr Felzmann Date: Mon, 17 Aug 2015 10:52:10 +0200 Subject: [PATCH 171/172] Fix formatting of print and printToPDF methods --- docs/api/web-view-tag.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 07d84324dd4b..f8490b624c73 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -315,11 +315,11 @@ Executes editing command `replace` in page. Executes editing command `replaceMisspelling` in page. -### `.print([options])` +### ``.print([options]) Prints webview's web page. Same with `webContents.print([options])`. -### `.printToPDF(options, callback)` +### ``.printToPDF(options, callback) Prints webview's web page as PDF, Same with `webContents.printToPDF(options, callback)` From 7842a90c5ed299fc13ea2b68d5bf8bd0198fa704 Mon Sep 17 00:00:00 2001 From: Petr Felzmann Date: Mon, 17 Aug 2015 15:03:04 +0200 Subject: [PATCH 172/172] Fix absolute url to github --- docs/api/remote.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index b01f47d169c4..0c31d7613529 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -20,7 +20,8 @@ var win = new BrowserWindow({ width: 800, height: 600 }); win.loadUrl('https://github.com'); ``` -Note: for the reverse (access renderer process from main process), you can use [webContents.executeJavascript](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#browserwindowwebcontents). +Note: for the reverse (access renderer process from main process), you can use +[webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code). ## Remote objects