diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 977a241a7d..7ee19783b0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -442,6 +442,10 @@ void Window::CapturePage(mate::Arguments* args) { rect, base::Bind(&OnCapturePageDone, args->isolate(), callback)); } +void Window::SetOffscreenRender(bool isOffscreen) { + window_->SetOffscreenRender(isOffscreen); +} + void Window::SetProgressBar(double progress) { window_->SetProgressBar(progress); } @@ -741,6 +745,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::IsVisibleOnAllWorkspaces) .SetMethod("sendMouseEvent", &Window::SendMouseEvent) .SetMethod("sendKeyboardEvent", &Window::SendKeyboardEvent) + .SetMethod("setOffscreenRender", &Window::SetOffscreenRender) #if defined(OS_MACOSX) .SetMethod("showDefinitionForSelection", &Window::ShowDefinitionForSelection) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 8bff976946..727cacd3d6 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -138,8 +138,10 @@ class Window : public mate::TrackableObject, void SetMenuBarVisibility(bool visible); bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); + void SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data); void SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data); + void SetOffscreenRender(bool isOffscreen); #if defined(OS_MACOSX) void ShowDefinitionForSelection(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index da7218d2ea..f28a3a8bd4 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -332,6 +332,29 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } +void NativeWindow::SetOffscreenRender(bool isOffscreen) { + if (!isOffscreen && !offscreen_) return; + + const auto view = web_contents()->GetRenderWidgetHostView(); + + if (view) { + if (isOffscreen) { + scoped_ptr subscriber( + new RenderSubscriber( + view->GetVisibleViewportSize(), + base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) + ) + ); + + view->BeginFrameSubscription(subscriber.Pass()); + } else { + view->EndFrameSubscription(); + } + + offscreen_ = isOffscreen; + } +} + void NativeWindow::RequestToClosePage() { bool prevent_default = false; FOR_EACH_OBSERVER(NativeWindowObserver, @@ -608,16 +631,7 @@ void NativeWindow::SendMouseWheelEvent(int modifiers, int x, int y, bool precise } void NativeWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - - if(offscreen_){ - scoped_ptr subscriber(new RenderSubscriber( - view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) - )); - - view->BeginFrameSubscription(subscriber.Pass()); - } + SetOffscreenRender(offscreen_); } void NativeWindow::RenderViewCreated( @@ -697,11 +711,12 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } -void NativeWindow::OnFrameReceived(bool result, scoped_refptr frame) { - if(result){ +void NativeWindow::OnFrameReceived(bool result, + scoped_refptr frame) { + if (result) { gfx::Rect rect = frame->visible_rect(); - const int rgb_arr_size = rect.width()*rect.height()*4; + const int rgb_arr_size = rect.width() * rect.height() * 4; scoped_ptr rgb_bytes(new uint8[rgb_arr_size]); // Convert a frame of YUV to 32 bit ARGB. @@ -712,7 +727,7 @@ void NativeWindow::OnFrameReceived(bool result, scoped_refptr rect.width(), rect.height(), frame->stride(media::VideoFrame::kYPlane), frame->stride(media::VideoFrame::kUVPlane), - rect.width()*4, + rect.width() * 4, media::YV12); FOR_EACH_OBSERVER(NativeWindowObserver, @@ -721,7 +736,8 @@ void NativeWindow::OnFrameReceived(bool result, scoped_refptr } } -bool RenderSubscriber::ShouldCaptureFrame(const gfx::Rect& damage_rect, +bool RenderSubscriber::ShouldCaptureFrame( + const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 88686ee22f..8cc1d2ff2b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -242,6 +242,8 @@ class NativeWindow : public content::WebContentsObserver, void SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount); void SendMouseWheelEvent(int modifiers, int x, int y, bool clickCount); + void SetOffscreenRender(bool isOffscreen); + protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); @@ -253,7 +255,6 @@ class NativeWindow : public content::WebContentsObserver, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void RenderViewReady() override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void BeforeUnloadDialogCancelled() override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 612b3ce4f3..f0b8abc279 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -74,6 +74,8 @@ You can also create a window without chrome by using Linux. * `standard-window` Boolean - Uses the OS X's standard window instead of the textured window. Defaults to `true`. + * `offscreen-render` Boolean - The frame of the window will be accessible + through the `frame-rendered` event in a buffer. Defaults to `false`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean - When setting `false`, it will disable the same-origin @@ -226,6 +228,15 @@ Emitted when devtools is closed. Emitted when devtools is focused / opened. +### Event: 'frame-rendered' + +* `event` Event +* `frame` Buffer +* `size` Number + +Emitted when *offscreen render* is enabled, the current frame's pixel data +and size are available. + ### Event: 'app-command': Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) is invoked. These are typically related to keyboard media keys or browser commands, as well as the "Back" button built into some mice on Windows. @@ -721,6 +732,11 @@ Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. +### BrowserWindow.setOffscreenRender(isOffscreen) + +Sets the offscreen rendering, if `true` the `frame-rendered` event will fire, +when the frame changes. + ## Class: WebContents A `WebContents` is responsible for rendering and controlling a web page.