fix a bug that caused a crash when using an offscreen window with detached devtools, related to autofill popups

This commit is contained in:
Heilig Benedek 2017-09-10 22:24:54 +02:00 committed by Cheng Zhao
parent 5daaff91ea
commit e39aacb30e
6 changed files with 31 additions and 8 deletions

View file

@ -933,9 +933,10 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
auto relay = NativeWindowRelay::FromWebContents(web_contents()); auto relay = NativeWindowRelay::FromWebContents(web_contents());
if (!relay) if (!relay)
return false; return false;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
IPC_END_MESSAGE_MAP()
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host) IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_ShowPopup,
relay->window.get(), NativeWindow::ShowAutofillPopup)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup, IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
relay->window.get(), NativeWindow::HideAutofillPopup) relay->window.get(), NativeWindow::HideAutofillPopup)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
@ -944,6 +945,16 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
return handled; return handled;
} }
void WebContents::ShowAutofillPopup(
content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
auto relay = NativeWindowRelay::FromWebContents(web_contents());
if (relay)
relay->window->ShowAutofillPopup(frame_host, this, bounds, values, labels);
}
// There are three ways of destroying a webContents: // There are three ways of destroying a webContents:
// 1. call webContents.destroy(); // 1. call webContents.destroy();
// 2. garbage collection; // 2. garbage collection;
@ -1624,7 +1635,7 @@ bool WebContents::IsOffScreen() const {
} }
bool WebContents::IsOffScreenOrEmbedderOffscreen() const { bool WebContents::IsOffScreenOrEmbedderOffscreen() const {
return IsOffScreen() || (embedder_ && embedder_->IsOffScreen()); return IsOffScreen() || (IsGuest() && embedder_ && embedder_->IsOffScreen());
} }
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) { void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {

View file

@ -357,6 +357,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DevToolsFocused() override; void DevToolsFocused() override;
void DevToolsOpened() override; void DevToolsOpened() override;
void DevToolsClosed() override; void DevToolsClosed() override;
void ShowAutofillPopup(
content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels);
private: private:
AtomBrowserContext* GetBrowserContext() const; AtomBrowserContext* GetBrowserContext() const;

View file

@ -11,6 +11,7 @@
#include <vector> #include <vector>
#include "atom/browser/native_window_observer.h" #include "atom/browser/native_window_observer.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/ui/accelerator_util.h" #include "atom/browser/ui/accelerator_util.h"
#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/atom_menu_model.h"
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
@ -231,6 +232,7 @@ class NativeWindow : public base::SupportsUserData,
const content::NativeWebKeyboardEvent& event) {} const content::NativeWebKeyboardEvent& event) {}
virtual void ShowAutofillPopup( virtual void ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
atom::api::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {} const std::vector<base::string16>& labels) {}

View file

@ -1357,14 +1357,15 @@ void NativeWindowViews::HandleKeyboardEvent(
void NativeWindowViews::ShowAutofillPopup( void NativeWindowViews::ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
atom::api::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) { const std::vector<base::string16>& labels) {
auto wc = atom::api::WebContents::FromWrappedClass( // auto wc = atom::api::WebContents::FromWrappedClass(
v8::Isolate::GetCurrent(), web_contents()); // v8::Isolate::GetCurrent(), web_contents());
autofill_popup_->CreateView( autofill_popup_->CreateView(
frame_host, frame_host,
wc->IsOffScreenOrEmbedderOffscreen(), web_contents->IsOffScreenOrEmbedderOffscreen(),
widget(), widget(),
bounds); bounds);
autofill_popup_->SetItems(values, labels); autofill_popup_->SetItems(values, labels);

View file

@ -190,6 +190,7 @@ class NativeWindowViews : public NativeWindow,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
void ShowAutofillPopup( void ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
atom::api::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) override; const std::vector<base::string16>& labels) override;

View file

@ -226,12 +226,13 @@ void AutofillPopupView::OnPaint(gfx::Canvas* canvas) {
SkBitmap bitmap; SkBitmap bitmap;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
cc::SkiaPaintCanvas* paint_canvas = nullptr;
if (view_proxy_.get()) { if (view_proxy_.get()) {
bitmap.allocN32Pixels(popup_->popup_bounds_in_view_.width(), bitmap.allocN32Pixels(popup_->popup_bounds_in_view_.width(),
popup_->popup_bounds_in_view_.height(), popup_->popup_bounds_in_view_.height(),
true); true);
cc::SkiaPaintCanvas paint_canvas(new SkCanvas(bitmap)); paint_canvas = new cc::SkiaPaintCanvas(bitmap);
draw_canvas = new gfx::Canvas(&paint_canvas, 1.0); draw_canvas = new gfx::Canvas(paint_canvas, 1.0);
} }
#endif #endif
@ -249,6 +250,7 @@ void AutofillPopupView::OnPaint(gfx::Canvas* canvas) {
if (view_proxy_.get()) { if (view_proxy_.get()) {
view_proxy_->SetBounds(popup_->popup_bounds_in_view_); view_proxy_->SetBounds(popup_->popup_bounds_in_view_);
view_proxy_->SetBitmap(bitmap); view_proxy_->SetBitmap(bitmap);
delete paint_canvas;
} }
#endif #endif
} }