Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: frameless mica/acrylic windows #39708

Merged
merged 7 commits into from Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions patches/chromium/.patches
Expand Up @@ -130,4 +130,5 @@ 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
@@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for a simple patch like this there is a chance upstreaming it, read the change log of the file and find the maintainer who has done related modifications, and ask them to review.


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;
}
10 changes: 1 addition & 9 deletions shell/browser/api/electron_api_browser_window.cc
Expand Up @@ -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.
Expand Down
47 changes: 39 additions & 8 deletions shell/browser/native_window.cc
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {}
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions shell/browser/native_window.h
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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};
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/native_window_mac.mm
Expand Up @@ -1458,6 +1458,8 @@ void ReorderChildWindowAbove(NSWindow* child_window, NSWindow* other_window) {
}

void NativeWindowMac::SetVibrancy(const std::string& type) {
NativeWindow::SetVibrancy(type);

NSVisualEffectView* vibrantView = [window_ vibrantView];

if (type.empty()) {
Expand Down
24 changes: 20 additions & 4 deletions shell/browser/native_window_views.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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
}

Expand Down