fix: ensure child window transparency (#28107)

* fix: ensure child window transparency works

Windows opened via window.open and intecepted via setWindowOpenHandler
or the `new-window` event should (a) have the correct background color
and (b) that background color should be transparent if specified.

The changes in api_web_contents fix (a) and the changes in
web_contents_preferences fix (b).

Notes: Child windows with specified background colors or transpency now
work as intended

* fix: set background_color in blink prefs apply logic

* fix: apply changes for 12

* fix: background_color patch simplification

* update patches

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: Electron Bot <electron@github.com>
This commit is contained in:
Keeley Hammond
2021-03-10 13:08:44 -08:00
committed by GitHub
parent f0500fae4c
commit 21ac61270a
6 changed files with 74 additions and 36 deletions

View File

@@ -626,6 +626,7 @@ WebContents.prototype._init = function () {
// it's technically a BrowserWindowConstructorOptions option because
// we need to access it in the renderer at init time.
backgroundColor: windowOpenOverriddenOptions.backgroundColor,
transparent: windowOpenOverriddenOptions.transparent,
...windowOpenOverriddenOptions.webPreferences
} : undefined;
this._setNextChildWebPreferences(

View File

@@ -110,3 +110,4 @@ don_t_use_potentially_null_getwebframe_-_view_when_get_blink.patch
cherry-pick-5902d1aa722a.patch
cherry-pick-5c7ad5393f74.patch
word_break_between_space_and_alphanumeric.patch
moves_background_color_setter_of_webview_to_blinks_webprefs_logic.patch

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Mon, 8 Mar 2021 16:27:39 -0800
Subject: moves background_color setter of WebView to blinks webprefs logic
background_color can be updated at runtime, as such we need to apply the
new background color to the WebView in the ApplyPreferences method.
There is no current way to attach an observer to these prefs so patching
is our only option.
Ideally we could add an embedder observer pattern here but that can be
done in future work.
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 755d037d6f5046d4641b6532918125d1ca84cdd8..adeb4845fe5f8516cb4d2ed36cb59bb26d714b9b 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -154,6 +154,7 @@
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
@@ -1752,6 +1753,14 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
RuntimeEnabledFeatures::SetTranslateServiceEnabled(
prefs.translate_service_available);
+
+ SkColor color = SK_ColorTRANSPARENT;
+ if (!prefs.guest_instance_id) { // not inside electron <webview /> tag, which is always transparent.
+ Color blink_color;
+ if (blink_color.SetFromString(WebString::FromASCII(prefs.background_color)))
+ color = static_cast<SkColor>(blink_color);
+ }
+ web_view->SetBaseBackgroundColor(color);
}
void WebViewImpl::ThemeChanged() {

View File

@@ -1055,6 +1055,16 @@ void WebContents::AddNewContents(
v8::HandleScope handle_scope(isolate);
auto api_web_contents =
CreateAndTake(isolate, std::move(new_contents), Type::kBrowserWindow);
// We call RenderFrameCreated here as at this point the empty "about:blank"
// render frame has already been created. If the window never navigates again
// RenderFrameCreated won't be called and certain prefs like
// "kBackgroundColor" will not be applied.
auto* frame = api_web_contents->MainFrame();
if (frame) {
api_web_contents->HandleNewRenderFrame(frame);
}
if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
initial_rect.x(), initial_rect.y(), initial_rect.width(),
initial_rect.height(), tracker->url, tracker->frame_name,
@@ -1353,30 +1363,27 @@ void WebContents::BeforeUnloadFired(bool proceed,
// there are two virtual functions named BeforeUnloadFired.
}
void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
if (!background_throttling_)
render_view_host->SetSchedulerThrottling(false);
// Set the background color of RenderWidgetHostView.
auto* const view = web_contents()->GetRenderWidgetHostView();
auto* web_preferences = WebContentsPreferences::From(web_contents());
if (view && web_preferences) {
std::string color_name;
if (web_preferences->GetPreference(options::kBackgroundColor,
&color_name)) {
view->SetBackgroundColor(ParseHexColor(color_name));
} else {
view->SetBackgroundColor(SK_ColorTRANSPARENT);
}
}
}
void WebContents::RenderFrameCreated(
void WebContents::HandleNewRenderFrame(
content::RenderFrameHost* render_frame_host) {
auto* rwhv = render_frame_host->GetView();
if (!rwhv)
return;
// Set the background color of RenderWidgetHostView.
auto* web_preferences = WebContentsPreferences::From(web_contents());
if (web_preferences) {
std::string color_name;
if (web_preferences->GetPreference(options::kBackgroundColor,
&color_name)) {
rwhv->SetBackgroundColor(ParseHexColor(color_name));
} else {
rwhv->SetBackgroundColor(SK_ColorTRANSPARENT);
}
}
if (!background_throttling_)
render_frame_host->GetRenderViewHost()->SetSchedulerThrottling(false);
auto* rwh_impl =
static_cast<content::RenderWidgetHostImpl*>(rwhv->GetRenderWidgetHost());
if (rwh_impl)
@@ -1385,6 +1392,11 @@ void WebContents::RenderFrameCreated(
WebFrameMain::RenderFrameCreated(render_frame_host);
}
void WebContents::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
HandleNewRenderFrame(render_frame_host);
}
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
// This event is necessary for tracking any states with respect to
// intermediate render view hosts aka speculative render view hosts. Currently

View File

@@ -211,6 +211,7 @@ class WebContents : public gin::Wrappable<WebContents>,
void IncrementCapturerCount(gin::Arguments* args);
void DecrementCapturerCount(gin::Arguments* args);
bool IsBeingCaptured();
void HandleNewRenderFrame(content::RenderFrameHost* render_frame_host);
#if BUILDFLAG(ENABLE_PRINTING)
void OnGetDefaultPrinter(base::Value print_settings,
@@ -550,7 +551,6 @@ class WebContents : public gin::Wrappable<WebContents>,
// content::WebContentsObserver:
void BeforeUnloadFired(bool proceed,
const base::TimeTicks& proceed_time) override;
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;

View File

@@ -265,22 +265,6 @@ void RendererClientBase::RenderFrameCreated(
// service_impl_.reset(new ElectronApiServiceImpl(render_frame, this));
new ElectronApiServiceImpl(render_frame, this);
content::RenderView* render_view = render_frame->GetRenderView();
if (render_frame->IsMainFrame() && render_view) {
blink::WebView* webview = render_view->GetWebView();
if (webview) {
auto prefs = render_frame->GetBlinkPreferences();
if (prefs.guest_instance_id) { // webview.
webview->SetBaseBackgroundColor(SK_ColorTRANSPARENT);
} else { // normal window.
std::string name = prefs.background_color;
SkColor color =
name.empty() ? SK_ColorTRANSPARENT : ParseHexColor(name);
webview->SetBaseBackgroundColor(color);
}
}
}
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
auto* dispatcher = extensions_renderer_client_->GetDispatcher();
// ExtensionFrameHelper destroys itself when the RenderFrame is destroyed.