Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/internal/cef_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ typedef struct _cef_settings_t {
/// opaque then the RGB components will be used as the background color. If
/// the alpha component is fully transparent for a windowed browser then the
/// default value of opaque white be used. If the alpha component is fully
/// transparent for a windowless (off-screen) browser then transparent
/// painting will be enabled.
/// transparent for a windowless (off-screen) browser or a frameless window
/// using Views framework then transparent painting will be enabled.
///
cef_color_t background_color;

Expand Down Expand Up @@ -704,8 +704,8 @@ typedef struct _cef_browser_settings_t {
/// opaque then the RGB components will be used as the background color. If
/// the alpha component is fully transparent for a windowed browser then the
/// CefSettings.background_color value will be used. If the alpha component is
/// fully transparent for a windowless (off-screen) browser then transparent
/// painting will be enabled.
/// fully transparent for a windowless (off-screen) browser or a frameless window
/// using Views framework then transparent painting will be enabled.
///
cef_color_t background_color;

Expand Down
3 changes: 2 additions & 1 deletion libcef/browser/browser_host_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,8 @@ int CefBrowserHostBase::browser_id() const {
SkColor CefBrowserHostBase::GetBackgroundColor() const {
// Don't use |platform_delegate_| because it's not thread-safe.
return CefContext::Get()->GetBackgroundColor(
&settings_, IsWindowless() ? STATE_ENABLED : STATE_DISABLED);
&settings_,
IsWindowless() || is_views_hosted() ? STATE_ENABLED : STATE_DISABLED);
}

content::WebContents* CefBrowserHostBase::GetWebContents() const {
Expand Down
8 changes: 5 additions & 3 deletions libcef/browser/browser_platform_delegate_create.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ std::unique_ptr<CefBrowserPlatformDelegateOsr> CreateOSRDelegate(
std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
const CefBrowserCreateParams& create_params) {
const bool is_windowless = create_params.IsWindowless();
const bool is_views_hosted = create_params.browser_view ||
create_params.popup_with_views_hosted_opener;
const SkColor background_color = CefContext::Get()->GetBackgroundColor(
&create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED);
&create_params.settings,
is_windowless || is_views_hosted ? STATE_ENABLED : STATE_DISABLED);

if (create_params.IsChromeStyle()) {
CefWindowInfo window_info;
Expand Down Expand Up @@ -97,8 +100,7 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
std::move(native_delegate));
}

if (create_params.browser_view ||
create_params.popup_with_views_hosted_opener) {
if (is_views_hosted) {
// CefWindowInfo is not used in this case.
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(CefWindowInfo(), background_color);
Expand Down
20 changes: 10 additions & 10 deletions libcef/browser/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ void InitCrashReporter() {

#endif // BUILDFLAG(IS_WIN)

bool GetColor(const cef_color_t cef_in, bool is_windowless, SkColor* sk_out) {
// Windowed browser colors must be fully opaque.
if (!is_windowless && CefColorGetA(cef_in) != SK_AlphaOPAQUE) {
bool GetColor(const cef_color_t cef_in, bool is_transparent, SkColor* sk_out) {
// transparent unsupported browser colors must be fully opaque.
if (!is_transparent && CefColorGetA(cef_in) != SK_AlphaOPAQUE) {
return false;
}

// Windowless browser colors may be fully transparent.
if (is_windowless && CefColorGetA(cef_in) == SK_AlphaTRANSPARENT) {
// transparent supported browser colors may be fully transparent.
if (is_transparent && CefColorGetA(cef_in) == SK_AlphaTRANSPARENT) {
*sk_out = SK_ColorTRANSPARENT;
return true;
}
Expand Down Expand Up @@ -444,19 +444,19 @@ bool CefContext::OnInitThread() {

SkColor CefContext::GetBackgroundColor(
const CefBrowserSettings* browser_settings,
cef_state_t windowless_state) const {
bool is_windowless = windowless_state == STATE_ENABLED
cef_state_t transparent_state) const {
bool is_transparent = transparent_state == STATE_ENABLED
? true
: (windowless_state == STATE_DISABLED
: (transparent_state == STATE_DISABLED
? false
: !!settings_.windowless_rendering_enabled);

// Default to opaque white if no acceptable color values are found.
SkColor sk_color = SK_ColorWHITE;

if (!browser_settings ||
!GetColor(browser_settings->background_color, is_windowless, &sk_color)) {
GetColor(settings_.background_color, is_windowless, &sk_color);
!GetColor(browser_settings->background_color, is_transparent, &sk_color)) {
GetColor(settings_.background_color, is_transparent, &sk_color);
}
return sk_color;
}
Expand Down
11 changes: 6 additions & 5 deletions libcef/browser/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ class CefContext {
// Returns the background color for the browser. If |browser_settings| is
// nullptr or does not specify a color then the global settings will be used.
// The alpha component will be either SK_AlphaTRANSPARENT or SK_AlphaOPAQUE
// (e.g. fully transparent or fully opaque). If |is_windowless| is
// (e.g. fully transparent or fully opaque). If |transparent_state| is
// STATE_DISABLED then SK_AlphaTRANSPARENT will always be returned. If
// |is_windowless| is STATE_ENABLED then SK_ColorTRANSPARENT may be returned
// to enable transparency for windowless browsers. See additional comments on
// CefSettings.background_color and CefBrowserSettings.background_color.
// |transparent_state| is STATE_ENABLED then SK_ColorTRANSPARENT may be returned
// to enable transparency for windowless browsers or a frameless
// window in Views. See additional comments on CefSettings.background_color
// and CefBrowserSettings.background_color.
SkColor GetBackgroundColor(const CefBrowserSettings* browser_settings,
cef_state_t windowless_state) const;
cef_state_t transparent_state) const;

CefTraceSubscriber* GetTraceSubscriber();
pref_helper::Registrar* GetPrefRegistrar();
Expand Down
13 changes: 13 additions & 0 deletions libcef/browser/views/window_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#endif
#endif

#include "cef/libcef/browser/chrome/views/chrome_browser_frame.h"
#include "cef/libcef/browser/context.h"
#include "cef/libcef/browser/geometry_util.h"
#include "cef/libcef/browser/image_impl.h"
#include "cef/libcef/browser/views/widget.h"
#include "cef/libcef/browser/views/window_impl.h"
#include "cef/libcef/features/runtime.h"
#include "ui/base/hit_test.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
Expand Down Expand Up @@ -521,6 +524,9 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
bool can_activate = true;
bool can_resize = true;

auto color = CefContext::Get()->GetBackgroundColor(nullptr, STATE_ENABLED);
bool is_translucent = color == SK_ColorTRANSPARENT;

const bool has_native_parent = parent_widget != gfx::kNullAcceleratedWidget;
if (has_native_parent) {
params.parent_widget = parent_widget;
Expand All @@ -539,6 +545,9 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
params.opacity = views::Widget::InitParams::WindowOpacity::kOpaque;
} else {
params.type = views::Widget::InitParams::TYPE_WINDOW;
if (is_translucent) {
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
}
}

if (cef_delegate()) {
Expand Down Expand Up @@ -727,6 +736,10 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
// |widget|.
host_widget_destruction_observer_ =
std::make_unique<WidgetDestructionObserver>(host_widget);

if (is_translucent) {
GetCefWindow()->SetBackgroundColor(SK_ColorTRANSPARENT);
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions tests/cefclient/browser/main_context_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
use_views_ = true;
}

// Whether transparent painting is used with windowless rendering.
const bool use_transparent_painting =
(use_windowless_rendering_ || use_views_) &&
command_line_->HasSwitch(switches::kTransparentPaintingEnabled);
if (use_views_ && use_transparent_painting &&
command_line->HasSwitch(switches::kHideFrame) &&
!command_line_->HasSwitch(switches::kUrl)) {
// Use the draggable regions test as the default URL for frameless windows.
main_url_ = "http://tests/transparent_views";
}

if (command_line_->HasSwitch(switches::kBackgroundColor)) {
// Parse the background color value.
background_color_ =
Expand Down
13 changes: 7 additions & 6 deletions tests/cefclient/browser/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@
#define IDS_SERVER_HTML 1021
#define IDS_TASK_MANAGER_HTML 1022
#define IDS_TRANSPARENCY_HTML 1023
#define IDS_URLREQUEST_HTML 1024
#define IDS_WEBSOCKET_HTML 1025
#define IDS_WINDOW_HTML 1026
#define IDS_WINDOW_ICON_1X_PNG 1027
#define IDS_WINDOW_ICON_2X_PNG 1028
#define IDS_XMLHTTPREQUEST_HTML 1029
#define IDS_TRANSPARENCT_VIEWS_HTML 1024
#define IDS_URLREQUEST_HTML 1025
#define IDS_WEBSOCKET_HTML 1026
#define IDS_WINDOW_HTML 1027
#define IDS_WINDOW_ICON_1X_PNG 1028
#define IDS_WINDOW_ICON_2X_PNG 1029
#define IDS_XMLHTTPREQUEST_HTML 1030

// Next default values for new objects
//
Expand Down
1 change: 1 addition & 0 deletions tests/cefclient/browser/resource_util_win_idmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ int GetResourceId(const char* resource_name) {
{"server.html", IDS_SERVER_HTML},
{"task_manager.html", IDS_TASK_MANAGER_HTML},
{"transparency.html", IDS_TRANSPARENCY_HTML},
{"transparent_views.html", IDS_TRANSPARENT_VIEWS_HTML},
{"urlrequest.html", IDS_URLREQUEST_HTML},
{"websocket.html", IDS_WEBSOCKET_HTML},
{"window.html", IDS_WINDOW_HTML},
Expand Down
64 changes: 64 additions & 0 deletions tests/cefclient/resources/transparent_views.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<html>
<head><title>Translucent Window Test</title>
<style>
#radius-window {
border-radius: 30px;
height: 400px;
width: 600px;
background: rgba(98, 98, 115);
opacity: 0.8;
}
#title-bar {
user-select: none;
margin-left: 30px;
margin-right: 30px;
display: flex;
background: rgb(88, 88, 105);
}
.draggable {
flex-grow: 2;
-webkit-app-region: drag;
height: 20px;
}
.controls {
flex-grow: 0;
font: 18px bold "Sans-serif";
color: red;
height: 20px;
width: 20px;
cursor: hand;
}
</style>
<script>
function changeAlpha(e) {
let w = document.getElementById("radius-window");
let opacity = w.style.opacity === "" ? 0.8 : parseFloat(w.style.opacity);
if (!e.shiftKey) {
opacity += 0.1;
} else {
opacity -= 0.1;
}
if (opacity <= 1 && opacity >= 0) {
w.style.opacity = opacity;
}
}
</script>
</head>
<body>
<div id="radius-window" onmousedown="changeAlpha(event);">
<div id="title-bar">
<div class="draggable"></div>
<div class="controls" onclick="window.close()">X</div>
</div>
Transparent window using Views framework can be enabled by setting the
alpha component of the CefSettings.background_color to fully transparent
(0x00) and returning true from IsFrameless() in CefWindowDelegate().
The transparent effect will propagate to
<a href="#" onClick="window.open(location.href, 'Popup'); return false;">popped up window</a>.
<br/>Window can be closed using JavaScript <a href="#" onClick="window.close(); return false;">window.close()</a>.
</p>
Click: decrease alpha component of the background.<br/>
Shift-Click: increase alpha component of the background.
</div>
</body>
</html>
1 change: 1 addition & 0 deletions tests/cefclient/win/cefclient.rc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ IDS_RESPONSE_FILTER_HTML BINARY "tests\\cefclient\\resources\\response_filter.ht
IDS_SERVER_HTML BINARY "tests\\cefclient\\resources\\server.html"
IDS_TASK_MANAGER_HTML BINARY "tests\\cefclient\\resources\\task_manager.html"
IDS_TRANSPARENCY_HTML BINARY "tests\\cefclient\\resources\\transparency.html"
IDS_TRANSPARENT_VIEWS_HTML BINARY "tests\\cefclient\\resources\\transparent_views.html"
IDS_URLREQUEST_HTML BINARY "tests\\cefclient\\resources\\urlrequest.html"
IDS_WEBSOCKET_HTML BINARY "tests\\cefclient\\resources\\websocket.html"
IDS_WINDOW_HTML BINARY "tests\\cefclient\\resources\\window.html"
Expand Down
6 changes: 6 additions & 0 deletions tests/cefsimple/simple_app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class SimpleWindowDelegate : public CefWindowDelegate {
browser_view_ = nullptr;
}

bool IsFrameless(CefRefPtr<CefWindow> window) override {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
return command_line->HasSwitch("hide-frame");
}

bool CanClose(CefRefPtr<CefWindow> window) override {
// Allow the window to close if the browser says it's OK.
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
Expand Down
14 changes: 14 additions & 0 deletions tests/ceftests/views/window_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,19 @@ void WindowAcceleratorImpl(CefRefPtr<CefWaitableEvent> event) {
TestWindowDelegate::RunTest(event, std::move(config));
}

void VerifyWindowTransparentBackground(CefRefPtr<CefWindow> window) {
// The transparent background color value from CefSettings.background_color
// by set in CefTestSuite::GetSettings() to enable transparent window
// in Views framework.
EXPECT_EQ(window->GetBackgroundColor(), 0u);
}

void WindowCreateTranslucentImpl(CefRefPtr<CefWaitableEvent> event) {
auto config = std::make_unique<TestWindowDelegate::Config>();
config->on_window_created = base::BindOnce(VerifyWindowTransparentBackground);
TestWindowDelegate::RunTest(event, std::move(config));
}

} // namespace

// Test window functionality. This is primarily to exercise exposed CEF APIs
Expand All @@ -591,6 +604,7 @@ WINDOW_TEST_ASYNC(WindowFullscreenFrameless)
WINDOW_TEST_ASYNC(WindowIcon)
WINDOW_TEST_ASYNC(WindowIconFrameless)
WINDOW_TEST_ASYNC(WindowAccelerator)
WINDOW_TEST_ASYNC(WindowCreateTranslucent)

namespace {

Expand Down