fix: frameless mica/acrylic windows (#39708)

* fix: backgroundMaterial works with frameless

* TODO: fix frameless mica/acrylic windows

* update caption color appropriately

* set background color properly

* refactor translucency method

* actualization
This commit is contained in:
Calvin 2023-09-11 06:51:54 -06:00 committed by GitHub
parent ab185c058f
commit d182794179
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 21 deletions

View file

@ -130,5 +130,6 @@ fix_harden_blink_scriptstate_maybefrom.patch
chore_add_buildflag_guard_around_new_include.patch
fix_use_delegated_generic_capturer_when_available.patch
build_remove_ent_content_analysis_assert.patch
fix_activate_background_material_on_windows.patch
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch

View file

@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <clavin@electronjs.org>
Date: Wed, 30 Aug 2023 18:15:36 -0700
Subject: fix: activate background material on windows
This patch adds a condition to the HWND message handler to allow windows
with translucent background materials to become activated.
This patch likely can't be upstreamed as-is, as Chromium doesn't have
this use case in mind currently.
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7bcd82612 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1094,7 +1094,7 @@ void HWNDMessageHandler::FrameTypeChanged() {
void HWNDMessageHandler::PaintAsActiveChanged() {
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
- !delegate_->HasFrame() ||
+ (!delegate_->HasFrame() && !is_translucent_) ||
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
return;
}

View file

@ -42,19 +42,11 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
auto web_preferences = gin_helper::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
bool transparent = false;
options.Get(options::kTransparent, &transparent);
std::string vibrancy_type;
#if BUILDFLAG(IS_MAC)
options.Get(options::kVibrancyType, &vibrancy_type);
#endif
// Copy the backgroundColor to webContents.
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
web_preferences.SetHidden(options::kBackgroundColor, color);
} else if (!vibrancy_type.empty() || transparent) {
} else if (window_->IsTranslucent()) {
// If the BrowserWindow is transparent or a vibrancy type has been set,
// also propagate transparency to the WebContents unless a separate
// backgroundColor has been set.

View file

@ -13,6 +13,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/browser/web_contents_user_data.h"
#include "include/core/SkColor.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_window_features.h"
#include "shell/browser/ui/drag_util.h"
@ -259,13 +260,15 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
SetBackgroundMaterial(material);
}
#endif
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(ParseCSSColor(color));
} else if (!transparent()) {
// For normal window, use white as default background.
SetBackgroundColor(SK_ColorWHITE);
SkColor background_color = SK_ColorWHITE;
if (std::string color; options.Get(options::kBackgroundColor, &color)) {
background_color = ParseCSSColor(color);
} else if (IsTranslucent()) {
background_color = SK_ColorTRANSPARENT;
}
SetBackgroundColor(background_color);
std::string title(Browser::Get()->GetName());
options.Get(options::kTitle, &title);
SetTitle(title);
@ -472,9 +475,13 @@ bool NativeWindow::AddTabbedWindow(NativeWindow* window) {
return true; // for non-Mac platforms
}
void NativeWindow::SetVibrancy(const std::string& type) {}
void NativeWindow::SetVibrancy(const std::string& type) {
vibrancy_ = type;
}
void NativeWindow::SetBackgroundMaterial(const std::string& type) {}
void NativeWindow::SetBackgroundMaterial(const std::string& type) {
background_material_ = type;
}
void NativeWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {}
@ -798,6 +805,30 @@ void NativeWindow::HandlePendingFullscreenTransitions() {
// static
int32_t NativeWindow::next_id_ = 0;
bool NativeWindow::IsTranslucent() const {
// Transparent windows are translucent
if (transparent()) {
return true;
}
#if BUILDFLAG(IS_MAC)
// Windows with vibrancy set are translucent
if (!vibrancy().empty()) {
return true;
}
#endif
#if BUILDFLAG(IS_WIN)
// Windows with certain background materials may be translucent
const std::string& bg_material = background_material();
if (!bg_material.empty() && bg_material != "none") {
return true;
}
#endif
return false;
}
// static
void NativeWindowRelay::CreateForWebContents(
content::WebContents* web_contents,

View file

@ -218,8 +218,12 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetAutoHideCursor(bool auto_hide);
// Vibrancy API
const std::string& vibrancy() const { return vibrancy_; }
virtual void SetVibrancy(const std::string& type);
const std::string& background_material() const {
return background_material_;
}
virtual void SetBackgroundMaterial(const std::string& type);
// Traffic Light API
@ -395,6 +399,8 @@ class NativeWindow : public base::SupportsUserData,
void AddDraggableRegionProvider(DraggableRegionProvider* provider);
void RemoveDraggableRegionProvider(DraggableRegionProvider* provider);
bool IsTranslucent() const;
protected:
friend class api::BrowserView;
@ -492,6 +498,9 @@ class NativeWindow : public base::SupportsUserData,
// Accessible title.
std::u16string accessible_title_;
std::string vibrancy_;
std::string background_material_;
gfx::Rect overlay_rect_;
base::WeakPtrFactory<NativeWindow> weak_factory_{this};

View file

@ -1456,6 +1456,8 @@ void NativeWindowMac::UpdateWindowOriginalFrame() {
}
void NativeWindowMac::SetVibrancy(const std::string& type) {
NativeWindow::SetVibrancy(type);
NSVisualEffectView* vibrantView = [window_ vibrantView];
if (type.empty()) {

View file

@ -284,12 +284,12 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
params.remove_standard_frame = !has_frame() || has_client_frame();
// If a client frame, we need to draw our own shadows.
if (transparent() || has_client_frame())
if (IsTranslucent() || has_client_frame())
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
// The given window is most likely not rectangular since it uses
// transparency and has no standard frame, don't show a shadow for it.
if (transparent() && !has_frame())
// The given window is most likely not rectangular since it is translucent and
// has no standard frame, don't show a shadow for it.
if (IsTranslucent() && !has_frame())
params.shadow_type = views::Widget::InitParams::ShadowType::kNone;
bool focusable;
@ -1457,6 +1457,8 @@ bool NativeWindowViews::IsMenuBarVisible() {
}
void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
NativeWindow::SetBackgroundMaterial(material);
#if BUILDFLAG(IS_WIN)
// DWMWA_USE_HOSTBACKDROPBRUSH is only supported on Windows 11 22H2 and up.
if (base::win::GetVersion() < base::win::Version::WIN11_22H2)
@ -1468,6 +1470,20 @@ void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
&backdrop_type, sizeof(backdrop_type));
if (FAILED(result))
LOG(WARNING) << "Failed to set background material to " << material;
// For frameless windows with a background material set, we also need to
// remove the caption color so it doesn't render a caption bar (since the
// window is frameless)
COLORREF caption_color = DWMWA_COLOR_DEFAULT;
if (backdrop_type != DWMSBT_NONE && backdrop_type != DWMSBT_AUTO &&
!has_frame()) {
caption_color = DWMWA_COLOR_NONE;
}
result = DwmSetWindowAttribute(GetAcceleratedWidget(), DWMWA_CAPTION_COLOR,
&caption_color, sizeof(caption_color));
if (FAILED(result))
LOG(WARNING) << "Failed to set caption color to transparent";
#endif
}