fix: abnormal behavior of windows background material (#47814)
* fix: abnormal behavior of windows background material Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> Co-authored-by: zoy <zoy-l@outlook.com> * chore: update patches Co-authored-by: patchup[bot] <73610968+patchup[bot]@users.noreply.github.com> * fix: setting background material after init Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: zoy <zoy-l@outlook.com> Co-authored-by: patchup[bot] <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
parent
658d52ecf1
commit
b20e91d86f
10 changed files with 195 additions and 107 deletions
|
@ -102,7 +102,6 @@ fix_use_delegated_generic_capturer_when_available.patch
|
||||||
expose_webblob_path_to_allow_embedders_to_get_file_paths.patch
|
expose_webblob_path_to_allow_embedders_to_get_file_paths.patch
|
||||||
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
|
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
|
||||||
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
|
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
|
||||||
fix_activate_background_material_on_windows.patch
|
|
||||||
feat_allow_passing_of_objecttemplate_to_objecttemplatebuilder.patch
|
feat_allow_passing_of_objecttemplate_to_objecttemplatebuilder.patch
|
||||||
chore_remove_check_is_test_on_script_injection_tracker.patch
|
chore_remove_check_is_test_on_script_injection_tracker.patch
|
||||||
fix_restore_original_resize_performance_on_macos.patch
|
fix_restore_original_resize_performance_on_macos.patch
|
||||||
|
@ -138,3 +137,4 @@ revert_update_siso-chromium_image.patch
|
||||||
build_set_mac_sdk_minimum_to_10.patch
|
build_set_mac_sdk_minimum_to_10.patch
|
||||||
partitionalloc_use_fewer_vmas_by_default_on_linux_systems.patch
|
partitionalloc_use_fewer_vmas_by_default_on_linux_systems.patch
|
||||||
fix_add_macos_memory_query_fallback_to_avoid_crash.patch
|
fix_add_macos_memory_query_fallback_to_avoid_crash.patch
|
||||||
|
fix_resolve_dynamic_background_material_update_issue_on_windows_11.patch
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: clavin <clavin@electronjs.org>
|
|
||||||
Date: Mon, 11 Dec 2023 20:43:34 -0300
|
|
||||||
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.
|
|
||||||
|
|
||||||
It also ensures the lParam of WM_NCACTIVATE is set to -1 so as to not repaint
|
|
||||||
the client area, which can lead to a title bar incorrectly being displayed in
|
|
||||||
frameless windows.
|
|
||||||
|
|
||||||
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 ad5044fbb4b8611a740da34f3f0bfe6dbb416f38..3762c5297e9009399df4ea3b45bf77326cd0f270 100644
|
|
||||||
--- a/ui/views/win/hwnd_message_handler.cc
|
|
||||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
|
||||||
@@ -939,13 +939,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
|
|
||||||
|
|
||||||
void HWNDMessageHandler::PaintAsActiveChanged() {
|
|
||||||
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
|
|
||||||
- !delegate_->HasFrame() ||
|
|
||||||
+ (!delegate_->HasFrame() && !is_translucent_) ||
|
|
||||||
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DefWindowProcWithRedrawLock(WM_NCACTIVATE, delegate_->ShouldPaintAsActive(),
|
|
||||||
- 0);
|
|
||||||
+ delegate_->HasFrame() ? 0 : -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon,
|
|
||||||
@@ -1734,7 +1734,7 @@ void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) {
|
|
||||||
if (delegate_->HasNonClientView() && !active &&
|
|
||||||
thread_id != GetCurrentThreadId()) {
|
|
||||||
// Update the native frame if it is rendering the non-client area.
|
|
||||||
- if (HasSystemFrame()) {
|
|
||||||
+ if (is_translucent_ || HasSystemFrame()) {
|
|
||||||
DefWindowProcWithRedrawLock(WM_NCACTIVATE, FALSE, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2342,17 +2342,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
|
|
||||||
delegate_->SchedulePaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
- // Calling DefWindowProc is only necessary if there's a system frame being
|
|
||||||
- // drawn. Otherwise it can draw an incorrect title bar and cause visual
|
|
||||||
- // corruption.
|
|
||||||
- if (!delegate_->HasFrame() ||
|
|
||||||
+ // If the window is translucent, it may have the Mica background.
|
|
||||||
+ // In that case, it's necessary to call |DefWindowProc|, but we can
|
|
||||||
+ // pass -1 in the lParam to prevent any non-client area elements from
|
|
||||||
+ // being displayed.
|
|
||||||
+ if ((!delegate_->HasFrame() && !is_translucent_) ||
|
|
||||||
delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) {
|
|
||||||
SetMsgHandled(TRUE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProcWithRedrawLock(WM_NCACTIVATE, paint_as_active || active,
|
|
||||||
- 0);
|
|
||||||
+ delegate_->HasFrame() ? 0 : -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT HWNDMessageHandler::OnNCCalcSize(BOOL mode, LPARAM l_param) {
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zoy <zoy-l@outlook.com>
|
||||||
|
Date: Mon, 5 May 2025 23:28:53 +0800
|
||||||
|
Subject: fix: resolve dynamic background material update issue on Windows 11
|
||||||
|
|
||||||
|
This patch addresses issues with background materials on Windows 11,
|
||||||
|
such as the background turning black when maximizing the window and
|
||||||
|
dynamic background material settings not taking effect.
|
||||||
|
|
||||||
|
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||||
|
index ca11e7008d3c528c643b760d0a7e980065f90629..9039ae483467c46f35370cd486e56537daaa9340 100644
|
||||||
|
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||||
|
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||||
|
@@ -179,6 +179,10 @@ void DesktopWindowTreeHostWin::FinishTouchDrag(gfx::Point screen_point) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void DesktopWindowTreeHostWin::SetIsTranslucent(bool is_translucent) {
|
||||||
|
+ message_handler_->set_is_translucent(is_translucent);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation:
|
||||||
|
|
||||||
|
void DesktopWindowTreeHostWin::Init(const Widget::InitParams& params) {
|
||||||
|
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||||
|
index 21049abeffd7b4bf314aec9fb5a63d5f773e53f5..04fcffd6bcfb7cbd18aa890e3cda259e842e23fa 100644
|
||||||
|
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||||
|
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
|
||||||
|
@@ -93,6 +93,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
|
||||||
|
// false.
|
||||||
|
void FinishTouchDrag(gfx::Point screen_point);
|
||||||
|
|
||||||
|
+ void SetIsTranslucent(bool is_translucent);
|
||||||
|
+
|
||||||
|
protected:
|
||||||
|
// Overridden from DesktopWindowTreeHost:
|
||||||
|
void Init(const Widget::InitParams& params) override;
|
||||||
|
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||||
|
index ad5044fbb4b8611a740da34f3f0bfe6dbb416f38..fc549cdff52393e8e7fb34f9c80be44adf6e171b 100644
|
||||||
|
--- a/ui/views/win/hwnd_message_handler.cc
|
||||||
|
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||||
|
@@ -939,13 +939,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
|
||||||
|
|
||||||
|
void HWNDMessageHandler::PaintAsActiveChanged() {
|
||||||
|
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
|
||||||
|
- !delegate_->HasFrame() ||
|
||||||
|
+ (!delegate_->HasFrame() && !is_translucent_) ||
|
||||||
|
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefWindowProcWithRedrawLock(WM_NCACTIVATE, delegate_->ShouldPaintAsActive(),
|
||||||
|
- 0);
|
||||||
|
+ delegate_->HasFrame() ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon,
|
||||||
|
@@ -1029,7 +1029,14 @@ void HWNDMessageHandler::SizeConstraintsChanged() {
|
||||||
|
// allowing ui::GetResizableFrameThickness() to be used consistently when
|
||||||
|
// removing the visible system frame.
|
||||||
|
const bool had_caption_on_init = window_style() & WS_CAPTION;
|
||||||
|
- const bool can_resize = !is_translucent_ && delegate_->CanResize();
|
||||||
|
+
|
||||||
|
+ // In Chromium, the !is_translucent_ check was introduced for Glic-specific
|
||||||
|
+ // behavior. Since Electron does not use Glic, this restriction can be safely
|
||||||
|
+ // removed. Keeping the is_translucent_ check disables maximization for
|
||||||
|
+ // translucent framed windows. Original code: !is_translucent_ &&
|
||||||
|
+ // delegate_->CanResize() See:
|
||||||
|
+ // https://chromium-review.googlesource.com/c/chromium/src/+/6372329
|
||||||
|
+ const bool can_resize = delegate_->CanResize();
|
||||||
|
const bool can_maximize = can_resize && delegate_->CanMaximize();
|
||||||
|
|
||||||
|
auto set_style_func = [&style](LONG bit, bool should_set) {
|
||||||
|
@@ -1624,11 +1631,16 @@ void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) {
|
||||||
|
// through, but that isn't the case when using Direct3D to draw transparent
|
||||||
|
// windows. So we route translucent windows throught to the delegate to
|
||||||
|
// allow for a custom hit mask.
|
||||||
|
- if (!is_translucent_ && !custom_window_region_.is_valid() &&
|
||||||
|
+ // patch: fix_resolve_dynamic_background_material_update_issue_on_windows_11
|
||||||
|
+ // Our translucent windows use the native frame by default, and we should not
|
||||||
|
+ // set a custom region when the window is maximized; otherwise, it will cause
|
||||||
|
+ // a white title bar to appear under Windows 11.
|
||||||
|
+ if (!custom_window_region_.is_valid() &&
|
||||||
|
(IsFrameSystemDrawn() || !delegate_->HasNonClientView())) {
|
||||||
|
if (force) {
|
||||||
|
SetWindowRgn(hwnd(), nullptr, redraw);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2342,17 +2354,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
|
||||||
|
delegate_->SchedulePaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Calling DefWindowProc is only necessary if there's a system frame being
|
||||||
|
- // drawn. Otherwise it can draw an incorrect title bar and cause visual
|
||||||
|
- // corruption.
|
||||||
|
- if (!delegate_->HasFrame() ||
|
||||||
|
+ // If the window is translucent, it may have the Mica background.
|
||||||
|
+ // In that case, it's necessary to call |DefWindowProc|, but we can
|
||||||
|
+ // pass -1 in the lParam to prevent any non-client area elements from
|
||||||
|
+ // being displayed.
|
||||||
|
+ if ((!delegate_->HasFrame() && !is_translucent_) ||
|
||||||
|
delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) {
|
||||||
|
SetMsgHandled(TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProcWithRedrawLock(WM_NCACTIVATE, paint_as_active || active,
|
||||||
|
- 0);
|
||||||
|
+ delegate_->HasFrame() ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT HWNDMessageHandler::OnNCCalcSize(BOOL mode, LPARAM l_param) {
|
|
@ -850,8 +850,8 @@ void BaseWindow::SetVibrancy(v8::Isolate* isolate,
|
||||||
window_->SetVibrancy(type, animation_duration_ms);
|
window_->SetVibrancy(type, animation_duration_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWindow::SetBackgroundMaterial(const std::string& material_type) {
|
void BaseWindow::SetBackgroundMaterial(const std::string& material) {
|
||||||
window_->SetBackgroundMaterial(material_type);
|
window_->SetBackgroundMaterial(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_MAC)
|
||||||
|
|
|
@ -196,7 +196,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||||
virtual void SetVibrancy(v8::Isolate* isolate,
|
virtual void SetVibrancy(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> value,
|
v8::Local<v8::Value> value,
|
||||||
gin_helper::Arguments* args);
|
gin_helper::Arguments* args);
|
||||||
void SetBackgroundMaterial(const std::string& vibrancy);
|
virtual void SetBackgroundMaterial(const std::string& material);
|
||||||
|
|
||||||
#if BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_MAC)
|
||||||
std::string GetAlwaysOnTopLevel() const;
|
std::string GetAlwaysOnTopLevel() const;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "shell/browser/api/electron_api_browser_window.h"
|
#include "shell/browser/api/electron_api_browser_window.h"
|
||||||
|
|
||||||
|
#include "base/containers/fixed_flat_set.h"
|
||||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||||
#include "content/public/browser/render_process_host.h"
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
@ -247,6 +248,18 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::SetBackgroundMaterial(const std::string& material) {
|
||||||
|
BaseWindow::SetBackgroundMaterial(material);
|
||||||
|
static constexpr auto materialTypes =
|
||||||
|
base::MakeFixedFlatSet<std::string_view>({"tabbed", "mica", "acrylic"});
|
||||||
|
|
||||||
|
if (materialTypes.contains(material)) {
|
||||||
|
SetBackgroundColor(ToRGBAHex(SK_ColorTRANSPARENT));
|
||||||
|
} else if (material == "none") {
|
||||||
|
SetBackgroundColor(ToRGBAHex(SK_ColorWHITE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BrowserWindow::FocusOnWebView() {
|
void BrowserWindow::FocusOnWebView() {
|
||||||
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
|
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ class BrowserWindow : public BaseWindow,
|
||||||
void Focus() override;
|
void Focus() override;
|
||||||
void Blur() override;
|
void Blur() override;
|
||||||
void SetBackgroundColor(const std::string& color_name) override;
|
void SetBackgroundColor(const std::string& color_name) override;
|
||||||
|
void SetBackgroundMaterial(const std::string& material) override;
|
||||||
void OnWindowShow() override;
|
void OnWindowShow() override;
|
||||||
void OnWindowHide() override;
|
void OnWindowHide() override;
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
// Vibrancy API
|
// Vibrancy API
|
||||||
virtual void SetVibrancy(const std::string& type, int duration);
|
virtual void SetVibrancy(const std::string& type, int duration);
|
||||||
|
|
||||||
|
const std::string& background_material() const {
|
||||||
|
return background_material_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SetBackgroundMaterial(const std::string& type);
|
virtual void SetBackgroundMaterial(const std::string& type);
|
||||||
|
|
||||||
// Traffic Light API
|
// Traffic Light API
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
#include "base/win/windows_version.h"
|
#include "base/win/windows_version.h"
|
||||||
#include "shell/browser/ui/views/win_frame_view.h"
|
#include "shell/browser/ui/views/win_frame_view.h"
|
||||||
#include "shell/browser/ui/win/electron_desktop_native_widget_aura.h"
|
#include "shell/browser/ui/win/electron_desktop_native_widget_aura.h"
|
||||||
|
#include "shell/browser/ui/win/electron_desktop_window_tree_host_win.h"
|
||||||
#include "shell/common/color_util.h"
|
#include "shell/common/color_util.h"
|
||||||
#include "skia/ext/skia_utils_win.h"
|
#include "skia/ext/skia_utils_win.h"
|
||||||
#include "ui/display/win/screen_win.h"
|
#include "ui/display/win/screen_win.h"
|
||||||
|
@ -352,6 +353,7 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
||||||
if (!has_frame()) {
|
if (!has_frame()) {
|
||||||
// Set Window style so that we get a minimize and maximize animation when
|
// Set Window style so that we get a minimize and maximize animation when
|
||||||
// frameless.
|
// frameless.
|
||||||
|
|
||||||
DWORD frame_style = WS_CAPTION | WS_OVERLAPPED;
|
DWORD frame_style = WS_CAPTION | WS_OVERLAPPED;
|
||||||
if (resizable_)
|
if (resizable_)
|
||||||
frame_style |= WS_THICKFRAME;
|
frame_style |= WS_THICKFRAME;
|
||||||
|
@ -685,13 +687,7 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
||||||
|
|
||||||
void NativeWindowViews::Maximize() {
|
void NativeWindowViews::Maximize() {
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
if (IsTranslucent()) {
|
if (transparent()) {
|
||||||
// Semi-transparent windows with backgroundMaterial not set to 'none', and
|
|
||||||
// not fully transparent, require manual handling of rounded corners when
|
|
||||||
// maximized.
|
|
||||||
if (rounded_corner_)
|
|
||||||
SetRoundedCorners(false);
|
|
||||||
|
|
||||||
restore_bounds_ = GetBounds();
|
restore_bounds_ = GetBounds();
|
||||||
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
||||||
GetNativeWindow());
|
GetNativeWindow());
|
||||||
|
@ -715,15 +711,10 @@ void NativeWindowViews::Unmaximize() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
if (IsTranslucent()) {
|
if (transparent()) {
|
||||||
SetBounds(restore_bounds_, false);
|
SetBounds(restore_bounds_, false);
|
||||||
NotifyWindowUnmaximize();
|
NotifyWindowUnmaximize();
|
||||||
if (transparent()) {
|
UpdateThickFrame();
|
||||||
UpdateThickFrame();
|
|
||||||
}
|
|
||||||
if (rounded_corner_) {
|
|
||||||
SetRoundedCorners(true);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -740,7 +731,7 @@ bool NativeWindowViews::IsMaximized() const {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
if (IsTranslucent() && !IsMinimized()) {
|
if (transparent() && !IsMinimized()) {
|
||||||
// If the window is the same dimensions and placement as the
|
// If the window is the same dimensions and placement as the
|
||||||
// display, we consider it maximized.
|
// display, we consider it maximized.
|
||||||
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
auto display = display::Screen::GetScreen()->GetDisplayNearestWindow(
|
||||||
|
@ -762,15 +753,10 @@ void NativeWindowViews::Minimize() {
|
||||||
|
|
||||||
void NativeWindowViews::Restore() {
|
void NativeWindowViews::Restore() {
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
if (IsMaximized() && IsTranslucent()) {
|
if (IsMaximized() && transparent()) {
|
||||||
SetBounds(restore_bounds_, false);
|
SetBounds(restore_bounds_, false);
|
||||||
NotifyWindowRestore();
|
NotifyWindowRestore();
|
||||||
if (transparent()) {
|
UpdateThickFrame();
|
||||||
UpdateThickFrame();
|
|
||||||
}
|
|
||||||
if (rounded_corner_) {
|
|
||||||
SetRoundedCorners(true);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -916,7 +902,7 @@ gfx::Size NativeWindowViews::GetContentSize() const {
|
||||||
|
|
||||||
gfx::Rect NativeWindowViews::GetNormalBounds() const {
|
gfx::Rect NativeWindowViews::GetNormalBounds() const {
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
if (IsMaximized() && IsTranslucent())
|
if (IsMaximized() && transparent())
|
||||||
return restore_bounds_;
|
return restore_bounds_;
|
||||||
#endif
|
#endif
|
||||||
return widget()->GetRestoredBounds();
|
return widget()->GetRestoredBounds();
|
||||||
|
@ -1557,25 +1543,53 @@ void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DWM_SYSTEMBACKDROP_TYPE backdrop_type = GetBackdropFromString(material);
|
DWM_SYSTEMBACKDROP_TYPE backdrop_type = GetBackdropFromString(material);
|
||||||
HRESULT result =
|
const bool is_translucent = backdrop_type != DWMSBT_NONE &&
|
||||||
DwmSetWindowAttribute(GetAcceleratedWidget(), DWMWA_SYSTEMBACKDROP_TYPE,
|
backdrop_type != DWMSBT_AUTO && !has_frame();
|
||||||
&backdrop_type, sizeof(backdrop_type));
|
|
||||||
|
HWND hwnd = GetAcceleratedWidget();
|
||||||
|
|
||||||
|
// We need to update margins ourselves since Chromium won't.
|
||||||
|
// See: ui/views/widget/widget_hwnd_utils.cc#157
|
||||||
|
// See: src/ui/views/win/hwnd_message_handler.cc#1793
|
||||||
|
MARGINS m = {0, 0, 0, 0};
|
||||||
|
if (is_translucent)
|
||||||
|
m = {-1, -1, -1, -1};
|
||||||
|
|
||||||
|
HRESULT result = DwmExtendFrameIntoClientArea(hwnd, &m);
|
||||||
|
if (FAILED(result))
|
||||||
|
LOG(WARNING) << "Failed to extend frame into client area";
|
||||||
|
|
||||||
|
result = DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE,
|
||||||
|
&backdrop_type, sizeof(backdrop_type));
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
LOG(WARNING) << "Failed to set background material to " << material;
|
LOG(WARNING) << "Failed to set background material to " << material;
|
||||||
|
|
||||||
|
auto* desktop_window_tree_host =
|
||||||
|
static_cast<ElectronDesktopWindowTreeHostWin*>(
|
||||||
|
GetNativeWindow()->GetHost());
|
||||||
|
|
||||||
|
// Synchronize the internal state; otherwise, the background material may not
|
||||||
|
// work properly.
|
||||||
|
if (desktop_window_tree_host) {
|
||||||
|
desktop_window_tree_host->SetIsTranslucent(is_translucent);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* desktop_native_widget_aura =
|
||||||
|
static_cast<ElectronDesktopNativeWidgetAura*>(widget()->native_widget());
|
||||||
|
desktop_native_widget_aura->UpdateWindowTransparency();
|
||||||
|
|
||||||
// For frameless windows with a background material set, we also need to
|
// 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
|
// remove the caption color so it doesn't render a caption bar (since the
|
||||||
// window is frameless)
|
// window is frameless)
|
||||||
COLORREF caption_color = DWMWA_COLOR_DEFAULT;
|
COLORREF caption_color =
|
||||||
if (backdrop_type != DWMSBT_NONE && backdrop_type != DWMSBT_AUTO &&
|
is_translucent ? DWMWA_COLOR_NONE : DWMWA_COLOR_DEFAULT;
|
||||||
!has_frame()) {
|
result = DwmSetWindowAttribute(hwnd, DWMWA_CAPTION_COLOR, &caption_color,
|
||||||
caption_color = DWMWA_COLOR_NONE;
|
sizeof(caption_color));
|
||||||
}
|
|
||||||
result = DwmSetWindowAttribute(GetAcceleratedWidget(), DWMWA_CAPTION_COLOR,
|
|
||||||
&caption_color, sizeof(caption_color));
|
|
||||||
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
LOG(WARNING) << "Failed to set caption color to transparent";
|
LOG(WARNING) << "Failed to set caption color to transparent";
|
||||||
|
|
||||||
|
// Activate the non-client area of the window
|
||||||
|
DefWindowProc(hwnd, WM_NCACTIVATE, TRUE, has_frame() ? 0 : -1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1897,7 +1911,7 @@ ui::mojom::WindowShowState NativeWindowViews::GetRestoredState() {
|
||||||
if (IsMaximized()) {
|
if (IsMaximized()) {
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
// Restore maximized state for windows that are not translucent.
|
// Restore maximized state for windows that are not translucent.
|
||||||
if (!IsTranslucent()) {
|
if (!transparent()) {
|
||||||
return ui::mojom::WindowShowState::kMaximized;
|
return ui::mojom::WindowShowState::kMaximized;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -64,7 +64,16 @@ bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels(
|
||||||
gfx::Insets* insets) const {
|
gfx::Insets* insets) const {
|
||||||
// Set DWMFrameInsets to prevent maximized frameless window from bleeding
|
// Set DWMFrameInsets to prevent maximized frameless window from bleeding
|
||||||
// into other monitors.
|
// into other monitors.
|
||||||
|
|
||||||
if (IsMaximized() && !native_window_view_->has_frame()) {
|
if (IsMaximized() && !native_window_view_->has_frame()) {
|
||||||
|
// We avoid doing this when the window is translucent (e.g. using
|
||||||
|
// backgroundMaterial effects), because setting zero insets can interfere
|
||||||
|
// with DWM rendering of blur or acrylic, potentially causing visual
|
||||||
|
// glitches.
|
||||||
|
const std::string& bg_material = native_window_view_->background_material();
|
||||||
|
if (!bg_material.empty() && bg_material != "none") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// This would be equivalent to calling:
|
// This would be equivalent to calling:
|
||||||
// DwmExtendFrameIntoClientArea({0, 0, 0, 0});
|
// DwmExtendFrameIntoClientArea({0, 0, 0, 0});
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue