Files
electron/patches/chromium/revert_views_remove_desktopwindowtreehostwin_window_enlargement.patch
electron-roller[bot] 6aaf490aa5 chore: bump chromium to 148.0.7768.0 (main) (#50599)
* chore: bump chromium in DEPS to 148.0.7765.0

* chore: bump chromium in DEPS to 148.0.7766.0

* fix(patch-conflict): update packed_resources dep name after upstream rename

Upstream renamed //chrome:packed_resources_integrity_header to
//chrome:packed_resources. Updated the patch to guard the new dependency
name with !is_electron_build while preserving the same intent.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714543

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(patch-conflict): update code_cache_host_impl.cc for upstream includes and TODO

Upstream added #include <stdint.h> and a TODO comment in
code_cache_host_impl.cc which conflicted with the Electron code cache
custom schemes patch. Resolved by keeping both upstream additions and
the Electron ProcessLockURLIsCodeCacheScheme function.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7615151

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: update patch hunk headers

Co-Authored-By: Claude <noreply@anthropic.com>

* 7700837: update RecordContentToVisibleTimeRequest from mojom to native struct

Upstream typemapped RecordContentToVisibleTimeRequest from a Mojo
struct to a native C++ struct. Updated OSR virtual method signatures
from blink::mojom::RecordContentToVisibleTimeRequestPtr to
std::optional<blink::RecordContentToVisibleTimeRequest> and
blink::RecordContentToVisibleTimeRequest to match.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7700837

Co-Authored-By: Claude <noreply@anthropic.com>

* 7714579: update WebString::FromASCII to FromUTF8

Upstream renamed blink::WebString::FromASCII to FromAscii. Updated
Electron's usage to FromUTF8 which is equivalent for ASCII scheme
strings and avoids a dependency on the renamed method. Also fixed
blink::String::FromUTF8 to use the String constructor directly.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714579

Co-Authored-By: Claude <noreply@anthropic.com>

* 7696480: add stream_info dep after StreamInfo extraction

Upstream extracted extensions::StreamInfo from PdfViewerStreamManager
to a standalone class in extensions/browser/mime_handler/stream_info.h.
Added the new target as a dependency since Electron's streams_private
and pdf_viewer_private APIs use PdfViewerStreamManager which now
depends on the separate StreamInfo target.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7696480

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: bump chromium in DEPS to 148.0.7768.0

* fix(patch-conflict): update PiP patch for new toggle_mute_button in overlay window

Upstream added a toggle_mute_button to the live caption dialog controls
in VideoOverlayWindowViews::SetLiveCaptionDialogVisibility. Extended the
existing #if 0 guard to include the new button handling since Electron
disables live caption dialog functionality.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7682308

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(patch-conflict): update packed_resource_integrity patch after upstream dep removal

Upstream removed the deps += [ "//chrome:packed_resources" ] line from
the if (!is_win) block in chrome/browser/BUILD.gn. The Electron patch
no longer needs to guard this dep with !is_electron_build in this
location since the dep was already relocated by an earlier upstream CL.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714543

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(patch-conflict): update WebSocket throttling revert for DisconnectWebSocketOnBFCache guard

Upstream added a DisconnectWebSocketOnBFCacheEnabled() runtime feature
check that wraps the WebSocket BFCache feature registration. Updated the
Electron revert patch to place the kAllowAggressiveThrottlingWithWebSocket
ternary inside the new conditional guard.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7698838

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(patch-conflict): update SCContentSharingPicker patch for upstream native picker refactor

Upstream added is_native_picker and filter_ based native picker session
validation to ScreenCaptureKitDeviceMac. Electron's patch uses its own
native picker approach (active_streams_ counter + direct SCContentSharingPicker
API), so marked the new upstream parameters as [[maybe_unused]] and kept
Electron's implementation.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7713560

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: update patch hunk headers

Co-Authored-By: Claude <noreply@anthropic.com>

* 7708800: update StartDragging signature to use RenderFrameHost

Upstream refactored StartDragging to take a RenderFrameHost& instead of
separate source_origin and source_rwh parameters. Updated
OffScreenWebContentsView to match the new signature and derive the
RenderWidgetHostImpl from the RenderFrameHost internally.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7708800

Co-Authored-By: Claude <noreply@anthropic.com>

* 7682308: add toggle_mute_button to chromium_src build sources

Upstream added a ToggleMuteButton to the PiP overlay window controls.
Added the new toggle_mute_button.cc/h source files to Electron's
chromium_src/BUILD.gn to resolve linker errors.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7682308

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: update patches after main rebase

* fixup! 7708800: update StartDragging signature to use RenderFrameHost

fix linting

* 7705541: [trap-handler] Track individual Wasm memories | https://chromium-review.googlesource.com/c/v8/v8/+/7705541

Moved the SetUpWebAssemblyTrapHandler() call to before the V8 isolate is created

* fixup! fix utility process tests

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2026-04-06 20:38:46 -07:00

286 lines
13 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <jkleinsc@electronjs.org>
Date: Sat, 14 Jun 2025 16:21:07 -0400
Subject: Revert "[views] Remove DesktopWindowTreeHostWin::window_enlargement_"
This reverts commit 1771dbae6961e7bb7c22bbc6c77f84d90ef2be46.
Electron needs this patch to allow windows smaller than 64x64
on Windows. We should refactor our code so that this patch isn't
necessary.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index d40db208ccc9955d38bab1c37e1c86a55ad7acf7..51c44e48902e44e7e1d6bda134a8f90e4bea3e81 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -22559,6 +22559,21 @@
]
}
],
+ "TransparentHwndEnlargement": [
+ {
+ "platforms": [
+ "windows"
+ ],
+ "experiments": [
+ {
+ "name": "DisableTransparentHwndEnlargement",
+ "disable_features": [
+ "EnableTransparentHwndEnlargement"
+ ]
+ }
+ ]
+ }
+ ],
"TransportSecurityFileWriterScheduleAndroid": [
{
"platforms": [
diff --git a/ui/views/views_features.cc b/ui/views/views_features.cc
index c74cf661f64e60ad6740e011f372e53426ce0c4d..77ce34e4f47a54f7ecabbd6e6d4d19555af248ff 100644
--- a/ui/views/views_features.cc
+++ b/ui/views/views_features.cc
@@ -34,6 +34,14 @@ BASE_FEATURE(kEnableInputProtection, base::FEATURE_DISABLED_BY_DEFAULT);
// crbug.com/370856871.
BASE_FEATURE(kEnableTouchDragCursorSync, base::FEATURE_ENABLED_BY_DEFAULT);
+// Enables enlargement of HWNDs to a minimum size of 64x64 to handle reported
+// graphical glitches on certain hardware.
+// TODO(crbug.com/401996981): Remove this once enlargement is confirmed to no
+// longer be needed.
+BASE_FEATURE(kEnableTransparentHwndEnlargement,
+ "EnableTransparentHwndEnlargement",
+ base::FEATURE_DISABLED_BY_DEFAULT);
+
// Used to enable keyboard-accessible tooltips in Views UI, as opposed
// to kKeyboardAccessibleTooltip in //ui/base/ui_base_features.cc.
BASE_FEATURE(kKeyboardAccessibleTooltipInViews,
diff --git a/ui/views/views_features.h b/ui/views/views_features.h
index 092e51509d4adccb8adbe2481909068e3e6836aa..5093a4c08bf6675ed1e5cb944c1bcb8251bdb033 100644
--- a/ui/views/views_features.h
+++ b/ui/views/views_features.h
@@ -16,6 +16,7 @@ VIEWS_EXPORT BASE_DECLARE_FEATURE(kAnnounceTextAdditionalAttributes);
VIEWS_EXPORT BASE_DECLARE_FEATURE(kApplyInitialUrlToWebContents);
VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableInputProtection);
VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTouchDragCursorSync);
+VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTransparentHwndEnlargement);
VIEWS_EXPORT BASE_DECLARE_FEATURE(kKeyboardAccessibleTooltipInViews);
} // namespace views::features
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 e4da40256ce94d6a0896792a8ef2faa18e1fa5d2..d1e06b675b19226cf3b78e1aada8d8f2d684fada 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
@@ -85,6 +85,23 @@ namespace {
// This constant controls how many pixels wide that border is.
const int kMouseCaptureRegionBorder = 5;
+gfx::Size GetExpandedWindowSize(bool is_translucent, gfx::Size size) {
+ if (!base::FeatureList::IsEnabled(
+ features::kEnableTransparentHwndEnlargement) ||
+ !is_translucent) {
+ return size;
+ }
+
+ // Some AMD drivers can't display windows that are less than 64x64 pixels,
+ // so expand them to be at least that size. http://crbug.com/286609
+ gfx::Size expanded(std::max(size.width(), 64), std::max(size.height(), 64));
+ return expanded;
+}
+
+void InsetBottomRight(gfx::Rect* rect, const gfx::Vector2d& vector) {
+ rect->Inset(gfx::Insets::TLBR(0, 0, vector.y(), vector.x()));
+}
+
// Updates the cursor clip region. Used for mouse locking.
void UpdateMouseLockRegion(aura::Window* window, bool locked) {
if (!locked) {
@@ -342,9 +359,14 @@ bool DesktopWindowTreeHostWin::IsVisible() const {
}
void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
- const gfx::Size size_in_pixels =
+ gfx::Size size_in_pixels =
display::win::GetScreenWin()->DIPToScreenSize(GetHWND(), size);
- message_handler_->SetSize(size_in_pixels);
+ gfx::Size expanded =
+ GetExpandedWindowSize(message_handler_->is_translucent(), size_in_pixels);
+ window_enlargement_ =
+ gfx::Vector2d(expanded.width() - size_in_pixels.width(),
+ expanded.height() - size_in_pixels.height());
+ message_handler_->SetSize(expanded);
}
void DesktopWindowTreeHostWin::StackAbove(aura::Window* window) {
@@ -359,30 +381,40 @@ void DesktopWindowTreeHostWin::StackAtTop() {
}
void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
- const gfx::Size size_in_pixels =
+ gfx::Size size_in_pixels =
display::win::GetScreenWin()->DIPToScreenSize(GetHWND(), size);
- message_handler_->CenterWindow(size_in_pixels);
+ gfx::Size expanded_size;
+ expanded_size =
+ GetExpandedWindowSize(message_handler_->is_translucent(), size_in_pixels);
+ window_enlargement_ =
+ gfx::Vector2d(expanded_size.width() - size_in_pixels.width(),
+ expanded_size.height() - size_in_pixels.height());
+ message_handler_->CenterWindow(expanded_size);
}
void DesktopWindowTreeHostWin::GetWindowPlacement(
gfx::Rect* bounds,
ui::mojom::WindowShowState* show_state) const {
message_handler_->GetWindowPlacement(bounds, show_state);
+ InsetBottomRight(bounds, window_enlargement_);
*bounds = display::win::GetScreenWin()->ScreenToDIPRect(GetHWND(), *bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
+ InsetBottomRight(&pixel_bounds, window_enlargement_);
return display::win::GetScreenWin()->ScreenToDIPRect(GetHWND(), pixel_bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
+ InsetBottomRight(&pixel_bounds, window_enlargement_);
return display::win::GetScreenWin()->ScreenToDIPRect(GetHWND(), pixel_bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
+ InsetBottomRight(&pixel_bounds, window_enlargement_);
return display::win::GetScreenWin()->ScreenToDIPRect(GetHWND(), pixel_bounds);
}
@@ -701,37 +733,44 @@ void DesktopWindowTreeHostWin::HideImpl() {
// other get/set methods work in DIP.
gfx::Rect DesktopWindowTreeHostWin::GetBoundsInPixels() const {
- const gfx::Rect bounds_px(message_handler_->GetClientAreaBounds());
+ gfx::Rect bounds(message_handler_->GetClientAreaBounds());
// If the window bounds were expanded we need to return the original bounds
// To achieve this we do the reverse of the expansion, i.e. add the
// window_expansion_top_left_delta_ to the origin and subtract the
// window_expansion_bottom_right_delta_ from the width and height.
- const gfx::Rect without_expansion_bounds_px(
- bounds_px.x() + window_expansion_top_left_delta_.x(),
- bounds_px.y() + window_expansion_top_left_delta_.y(),
- bounds_px.width() - window_expansion_bottom_right_delta_.x(),
- bounds_px.height() - window_expansion_bottom_right_delta_.y());
- return without_expansion_bounds_px;
+ gfx::Rect without_expansion(
+ bounds.x() + window_expansion_top_left_delta_.x(),
+ bounds.y() + window_expansion_top_left_delta_.y(),
+ bounds.width() - window_expansion_bottom_right_delta_.x() -
+ window_enlargement_.x(),
+ bounds.height() - window_expansion_bottom_right_delta_.y() -
+ window_enlargement_.y());
+ return without_expansion;
}
-void DesktopWindowTreeHostWin::SetBoundsInPixels(
- const gfx::Rect& bounds_in_pixels) {
+void DesktopWindowTreeHostWin::SetBoundsInPixels(const gfx::Rect& bounds) {
// If the window bounds have to be expanded we need to subtract the
// window_expansion_top_left_delta_ from the origin and add the
// window_expansion_bottom_right_delta_ to the width and height
- const gfx::Size old_content_size_px = GetBoundsInPixels().size();
-
- const gfx::Rect expanded_bounds_px(
- bounds_in_pixels.x() - window_expansion_top_left_delta_.x(),
- bounds_in_pixels.y() - window_expansion_top_left_delta_.y(),
- bounds_in_pixels.width() + window_expansion_bottom_right_delta_.x(),
- bounds_in_pixels.height() + window_expansion_bottom_right_delta_.y());
-
- // When `expanded_bounds_px` causes the window to be moved to a display with a
+ gfx::Size old_content_size = GetBoundsInPixels().size();
+
+ gfx::Rect expanded(
+ bounds.x() - window_expansion_top_left_delta_.x(),
+ bounds.y() - window_expansion_top_left_delta_.y(),
+ bounds.width() + window_expansion_bottom_right_delta_.x(),
+ bounds.height() + window_expansion_bottom_right_delta_.y());
+
+ gfx::Rect new_expanded(
+ expanded.origin(),
+ GetExpandedWindowSize(message_handler_->is_translucent(),
+ expanded.size()));
+ window_enlargement_ =
+ gfx::Vector2d(new_expanded.width() - expanded.width(),
+ new_expanded.height() - expanded.height());
+ // When |new_expanded| causes the window to be moved to a display with a
// different DSF, HWNDMessageHandler::OnDpiChanged() will be called and the
// window size will be scaled automatically.
- message_handler_->SetBounds(expanded_bounds_px,
- old_content_size_px != bounds_in_pixels.size());
+ message_handler_->SetBounds(new_expanded, old_content_size != bounds.size());
}
gfx::Rect
@@ -943,18 +982,26 @@ int DesktopWindowTreeHostWin::GetNonClientComponent(
void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size_px,
SkPath* path) {
- Widget* widget = GetWidget();
- if (!widget || !widget->non_client_view()) {
- return;
- }
+ // Request the window mask for hwnd of `size_px`. The hwnd size must be
+ // adjusted by `window_enlargement` to return to the client-expected window
+ // size (see crbug.com/41047830).
+ const gfx::Size adjusted_size_in_px =
+ size_px - gfx::Size(window_enlargement_.x(), window_enlargement_.y());
- widget->non_client_view()->GetWindowMask(
- display::win::GetScreenWin()->ScreenToDIPSize(GetHWND(), size_px), path);
- // Convert path in DIPs to pixels.
- if (!path->isEmpty()) {
- const float scale =
- display::win::GetScreenWin()->GetScaleFactorForHWND(GetHWND());
- *path = path->makeTransform(SkMatrix::Scale(scale, scale));
+ if (Widget* widget = GetWidget(); widget && widget->non_client_view()) {
+ widget->non_client_view()->GetWindowMask(
+ display::win::GetScreenWin()->ScreenToDIPSize(GetHWND(),
+ adjusted_size_in_px),
+ path);
+ // Convert path in DIPs to pixels.
+ if (!path->isEmpty()) {
+ const float scale =
+ display::win::GetScreenWin()->GetScaleFactorForHWND(GetHWND());
+ *path = path->makeTransform(SkMatrix::Scale(scale, scale));
+ }
+ } else if (!window_enlargement_.IsZero()) {
+ *path = SkPath::Rect(SkRect::MakeXYWH(0, 0, adjusted_size_in_px.width(),
+ adjusted_size_in_px.height()));
}
}
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 27322ef34edf3fa8bfbd20b1baddcaf3b7555618..a40bd9f25fa07a553c011cf19f155f8158f4ae5f 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
@@ -175,7 +175,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void ShowImpl() override;
void HideImpl() override;
gfx::Rect GetBoundsInPixels() const override;
- void SetBoundsInPixels(const gfx::Rect& bounds_in_pixels) override;
+ void SetBoundsInPixels(const gfx::Rect& bounds) override;
gfx::Rect GetBoundsInAcceleratedWidgetPixelCoordinates() override;
gfx::Point GetLocationOnScreenInPixels() const override;
void SetCapture() override;
@@ -330,6 +330,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
gfx::Vector2d window_expansion_top_left_delta_;
gfx::Vector2d window_expansion_bottom_right_delta_;
+ // Windows are enlarged to be at least 64x64 pixels, so keep track of the
+ // extra added here.
+ // TODO(crbug.com/401996981): This is likely no longer necessary and should be
+ // removed.
+ gfx::Vector2d window_enlargement_;
+
// Whether the window close should be converted to a hide, and then actually
// closed on the completion of the hide animation. This is cached because
// the property is set on the contained window which has a shorter lifetime.