Skip to content

Commit 7624958

Browse files
authored
Merge pull request electron#6723 from electron/dummy-view
Show a dummy view in the offscreen window
2 parents 32d9382 + c0c7b81 commit 7624958

12 files changed

+113
-61
lines changed

atom/browser/api/atom_api_web_contents.cc

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ WebContents::WebContents(v8::Isolate* isolate,
314314
options.Get("transparent", &transparent);
315315

316316
content::WebContents::CreateParams params(session->browser_context());
317-
auto* view = new OffScreenWebContentsView(transparent);
317+
auto* view = new OffScreenWebContentsView(
318+
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
318319
params.view = view;
319320
params.delegate_view = view;
320321

@@ -608,15 +609,8 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) {
608609

609610
void WebContents::DocumentLoadedInFrame(
610611
content::RenderFrameHost* render_frame_host) {
611-
if (!render_frame_host->GetParent()) {
612-
if (IsOffScreen()) {
613-
auto* rwhv = web_contents()->GetRenderWidgetHostView();
614-
static_cast<OffScreenRenderWidgetHostView*>(rwhv)->SetPaintCallback(
615-
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
616-
}
617-
612+
if (!render_frame_host->GetParent())
618613
Emit("dom-ready");
619-
}
620614
}
621615

622616
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
@@ -1344,19 +1338,14 @@ bool WebContents::IsOffScreen() const {
13441338
}
13451339

13461340
void WebContents::OnPaint(const gfx::Rect& dirty_rect,
1347-
const gfx::Size& bitmap_size,
1348-
int pixel_size,
1349-
void* bitmap_pixels) {
1341+
const SkBitmap& bitmap) {
13501342
v8::MaybeLocal<v8::Object> buffer = node::Buffer::Copy(
1351-
isolate(), reinterpret_cast<char*>(bitmap_pixels),
1352-
pixel_size * bitmap_size.width() * bitmap_size.height());
1353-
1354-
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate());
1355-
dict.Set("width", bitmap_size.width());
1356-
dict.Set("height", bitmap_size.height());
1357-
1358-
if (!buffer.IsEmpty())
1359-
Emit("paint", dirty_rect, buffer.ToLocalChecked(), dict);
1343+
isolate(),
1344+
reinterpret_cast<char*>(bitmap.getPixels()), bitmap.getSize());
1345+
if (!buffer.IsEmpty()) {
1346+
Emit("paint", dirty_rect, buffer.ToLocalChecked(),
1347+
gfx::Size(bitmap.width(), bitmap.height()));
1348+
}
13601349
}
13611350

13621351
void WebContents::StartPainting() {

atom/browser/api/atom_api_web_contents.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
158158

159159
// Methods for offscreen rendering
160160
bool IsOffScreen() const;
161-
void OnPaint(const gfx::Rect& dirty_rect,
162-
const gfx::Size& bitmap_size,
163-
const int pixel_size,
164-
void* bitmap_pixels);
161+
void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap);
165162
void StartPainting();
166163
void StopPainting();
167164
bool IsPainting() const;

atom/browser/osr/osr_output_device.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
8686
return;
8787

8888
SkAutoLockPixels bitmap_pixels_lock(*bitmap_);
89-
callback_.Run(rect, gfx::Size(bitmap_->width(), bitmap_->height()),
90-
bitmap_->bytesPerPixel(), bitmap_->getPixels());
89+
callback_.Run(rect, *bitmap_);
9190
}
9291

9392
} // namespace atom

atom/browser/osr/osr_output_device.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
namespace atom {
1414

15-
typedef base::Callback<void(const gfx::Rect&, const gfx::Size&,
16-
const int, void*)> OnPaintCallback;
15+
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
1716

1817
class OffScreenOutputDevice : public cc::SoftwareOutputDevice {
1918
public:

atom/browser/osr/osr_render_widget_host_view.cc

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,7 @@ class AtomCopyFrameGenerator {
260260
const gfx::Rect& damage_rect,
261261
const SkBitmap& bitmap,
262262
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock) {
263-
view_->OnPaint(damage_rect,
264-
gfx::Size(bitmap.width(), bitmap.height()),
265-
bitmap.bytesPerPixel(), bitmap.getPixels());
263+
view_->OnPaint(damage_rect, bitmap);
266264

267265
if (frame_retry_count_ > 0)
268266
frame_retry_count_ = 0;
@@ -338,15 +336,17 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
338336

339337
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
340338
bool transparent,
339+
const OnPaintCallback& callback,
341340
content::RenderWidgetHost* host,
342341
NativeWindow* native_window)
343342
: render_widget_host_(content::RenderWidgetHostImpl::From(host)),
344343
native_window_(native_window),
345344
software_output_device_(nullptr),
345+
transparent_(transparent),
346+
callback_(callback),
346347
frame_rate_(60),
347348
frame_rate_threshold_ms_(0),
348349
last_time_(base::Time::Now()),
349-
transparent_(transparent),
350350
scale_factor_(kDefaultScaleFactor),
351351
is_showing_(!render_widget_host_->is_hidden()),
352352
size_(native_window->GetSize()),
@@ -754,7 +754,8 @@ std::unique_ptr<cc::SoftwareOutputDevice>
754754
DCHECK(!copy_frame_generator_);
755755
DCHECK(!software_output_device_);
756756

757-
software_output_device_ = new OffScreenOutputDevice(transparent_,
757+
software_output_device_ = new OffScreenOutputDevice(
758+
transparent_,
758759
base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
759760
weak_ptr_factory_.GetWeakPtr()));
760761
return base::WrapUnique(software_output_device_);
@@ -783,20 +784,10 @@ void OffScreenRenderWidgetHostView::OnSetNeedsBeginFrames(bool enabled) {
783784
}
784785
}
785786

786-
void OffScreenRenderWidgetHostView::SetPaintCallback(
787-
const OnPaintCallback& callback) {
788-
callback_ = callback;
789-
}
790-
791787
void OffScreenRenderWidgetHostView::OnPaint(
792-
const gfx::Rect& damage_rect,
793-
const gfx::Size& bitmap_size,
794-
const int pixel_size,
795-
void* bitmap_pixels) {
788+
const gfx::Rect& damage_rect, const SkBitmap& bitmap) {
796789
TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint");
797-
798-
if (!callback_.is_null())
799-
callback_.Run(damage_rect, bitmap_size, pixel_size, bitmap_pixels);
790+
callback_.Run(damage_rect, bitmap);
800791
}
801792

802793
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {

atom/browser/osr/osr_render_widget_host_view.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class OffScreenRenderWidgetHostView
6363
public content::DelegatedFrameHostClient {
6464
public:
6565
OffScreenRenderWidgetHostView(bool transparent,
66+
const OnPaintCallback& callback,
6667
content::RenderWidgetHost* render_widget_host,
6768
NativeWindow* native_window);
6869
~OffScreenRenderWidgetHostView() override;
@@ -189,11 +190,7 @@ class OffScreenRenderWidgetHostView
189190
void DestroyPlatformWidget();
190191
#endif
191192

192-
void SetPaintCallback(const OnPaintCallback& callback);
193-
void OnPaint(const gfx::Rect& damage_rect,
194-
const gfx::Size& bitmap_size,
195-
const int pixel_size,
196-
void* bitmap_pixels);
193+
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
197194

198195
void SetPainting(bool painting);
199196
bool IsPainting() const;
@@ -214,14 +211,14 @@ class OffScreenRenderWidgetHostView
214211
NativeWindow* native_window_;
215212
OffScreenOutputDevice* software_output_device_;
216213

214+
const bool transparent_;
217215
OnPaintCallback callback_;
218216

219217
int frame_rate_;
220218
int frame_rate_threshold_ms_;
221219

222220
base::Time last_time_;
223221

224-
const bool transparent_;
225222
float scale_factor_;
226223
bool is_showing_;
227224
gfx::Vector2dF last_scroll_offset_;

atom/browser/osr/osr_web_contents_view.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@
66

77
namespace atom {
88

9-
OffScreenWebContentsView::OffScreenWebContentsView(bool transparent)
9+
OffScreenWebContentsView::OffScreenWebContentsView(
10+
bool transparent, const OnPaintCallback& callback)
1011
: transparent_(transparent),
12+
callback_(callback),
1113
web_contents_(nullptr) {
14+
#if defined(OS_MACOSX)
15+
PlatformCreate();
16+
#endif
1217
}
1318

1419
OffScreenWebContentsView::~OffScreenWebContentsView() {
20+
#if defined(OS_MACOSX)
21+
PlatformDestroy();
22+
#endif
1523
}
1624

1725
void OffScreenWebContentsView::SetWebContents(
1826
content::WebContents* web_contents) {
1927
web_contents_ = web_contents;
2028
}
2129

30+
#if !defined(OS_MACOSX)
2231
gfx::NativeView OffScreenWebContentsView::GetNativeView() const {
2332
return gfx::NativeView();
2433
}
@@ -30,6 +39,7 @@ gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const {
3039
gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const {
3140
return gfx::NativeWindow();
3241
}
42+
#endif
3343

3444
void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const {
3545
*out = GetViewBounds();
@@ -66,17 +76,17 @@ content::RenderWidgetHostViewBase*
6676
OffScreenWebContentsView::CreateViewForWidget(
6777
content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) {
6878
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
69-
view_ = new OffScreenRenderWidgetHostView(transparent_, render_widget_host,
70-
relay->window.get());
79+
view_ = new OffScreenRenderWidgetHostView(
80+
transparent_, callback_, render_widget_host, relay->window.get());
7181
return view_;
7282
}
7383

7484
content::RenderWidgetHostViewBase*
7585
OffScreenWebContentsView::CreateViewForPopupWidget(
7686
content::RenderWidgetHost* render_widget_host) {
7787
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
78-
view_ = new OffScreenRenderWidgetHostView(transparent_, render_widget_host,
79-
relay->window.get());
88+
view_ = new OffScreenRenderWidgetHostView(
89+
transparent_, callback_, render_widget_host, relay->window.get());
8090
return view_;
8191
}
8292

atom/browser/osr/osr_web_contents_view.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,25 @@
1010
#include "content/browser/web_contents/web_contents_view.h"
1111
#include "content/public/browser/web_contents.h"
1212

13+
#if defined(OS_MACOSX)
14+
#ifdef __OBJC__
15+
@class OffScreenView;
16+
#else
17+
class OffScreenView;
18+
#endif
19+
#endif
20+
1321
namespace atom {
1422

1523
class OffScreenWebContentsView : public content::WebContentsView,
1624
public content::RenderViewHostDelegateView {
1725
public:
18-
explicit OffScreenWebContentsView(bool transparent);
26+
OffScreenWebContentsView(bool transparent, const OnPaintCallback& callback);
1927
~OffScreenWebContentsView();
2028

2129
void SetWebContents(content::WebContents*);
2230

23-
// content::WebContentsView
31+
// content::WebContentsView:
2432
gfx::NativeView GetNativeView() const override;
2533
gfx::NativeView GetContentNativeView() const override;
2634
gfx::NativeWindow GetTopLevelNativeWindow() const override;
@@ -61,11 +69,21 @@ class OffScreenWebContentsView : public content::WebContentsView,
6169
void UpdateDragCursor(blink::WebDragOperation operation) override;
6270

6371
private:
72+
#if defined(OS_MACOSX)
73+
void PlatformCreate();
74+
void PlatformDestroy();
75+
#endif
76+
6477
const bool transparent_;
78+
OnPaintCallback callback_;
6579

6680
// Weak refs.
6781
OffScreenRenderWidgetHostView* view_;
6882
content::WebContents* web_contents_;
83+
84+
#if defined(OS_MACOSX)
85+
OffScreenView* offScreenView_;
86+
#endif
6987
};
7088

7189
} // namespace atom
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2016 GitHub, Inc.
2+
// Use of this source code is governed by the MIT license that can be
3+
// found in the LICENSE file.
4+
5+
#include "atom/browser/osr/osr_web_contents_view.h"
6+
7+
@interface OffScreenView : NSView
8+
@end
9+
10+
@implementation OffScreenView
11+
12+
- (void)drawRect:(NSRect)dirtyRect {
13+
NSString* str = @"No content under offscreen mode";
14+
NSMutableParagraphStyle* paragraphStyle =
15+
[[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
16+
[paragraphStyle setAlignment:NSCenterTextAlignment];
17+
NSDictionary* attributes = [NSDictionary
18+
dictionaryWithObject:paragraphStyle
19+
forKey:NSParagraphStyleAttributeName];
20+
NSAttributedString* text =
21+
[[[NSAttributedString alloc] initWithString:str
22+
attributes:attributes] autorelease];
23+
NSRect frame = NSMakeRect(0, (self.frame.size.height - text.size.height) / 2,
24+
self.frame.size.width, text.size.height);
25+
[str drawInRect:frame withAttributes:attributes];
26+
}
27+
28+
@end
29+
30+
namespace atom {
31+
32+
gfx::NativeView OffScreenWebContentsView::GetNativeView() const {
33+
return offScreenView_;
34+
}
35+
36+
gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const {
37+
return offScreenView_;
38+
}
39+
40+
gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const {
41+
return [offScreenView_ window];
42+
}
43+
44+
void OffScreenWebContentsView::PlatformCreate() {
45+
offScreenView_ = [[OffScreenView alloc] init];
46+
}
47+
48+
void OffScreenWebContentsView::PlatformDestroy() {
49+
[offScreenView_ release];
50+
}
51+
52+
} // namespace atom

docs/api/web-contents.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ Returns:
471471
* `bitmapSize` Object
472472
* `width` Number - the width of the whole bitmap
473473
* `height` Number - the height of the whole bitmap
474-
* `bytesPerPixel` Number - The number of bytes per pixel in the bitmap
475474

476475
Emitted when a new frame is generated. Only the dirty area is passed in the
477476
buffer.

0 commit comments

Comments
 (0)