From a41a5718b1921ab99e2699a7e2f3727ed3fc3d62 Mon Sep 17 00:00:00 2001 From: Tariq Bashir Date: Fri, 29 May 2026 18:46:54 +0100 Subject: [PATCH] fix: restore original bounds after CenterWindow clamps to primary display OS-21449 When creating a frameless BrowserWindow spanning multiple displays (e.g. 3840x1080 across dual HDMI), CenterWindow in the NativeWindowViews constructor clamps the size to the primary display's work area (1920x1080). InitFromOptions then called SetPosition(x, y), which only updated the position and preserved the clamped size, so the window was permanently stuck at 1920x1080. Fix: change InitFromOptions to call SetBounds with the full rect (position + original size from options) instead of SetPosition, restoring the intended dimensions after CenterWindow's clamping. This regression was introduced by upstream Electron commit 4affacb4e1 ("fix: external resize hit targets for frameless windows on Windows", PR #50864). That commit added a guard condition `if (!GetRestoredFrameBorderInsets().IsEmpty())` around a post-CenterWindow SetBounds call in the NativeWindowViews constructor, which previously ran unconditionally on Linux. For frameless windows (where frame border insets are zero), the SetBounds is now skipped, leaving CenterWindow's clamped size in effect. In Electron 28, the unconditional SetBounds after CenterWindow always restored the original requested size: // On linux after the widget is initialized we might have to force set the // bounds if the bounds are smaller than the current display SetBounds(gfx::Rect(GetPosition(), bounds.size()), false); This was preserved in commit 931c257de7 (PR #49209, "accurate window sizing and support for content sizing on Linux/Wayland with CSD"), which even documented the intent: "The widget clamps bounds to fit the screen, but we want to allow windows larger than the display." The subsequent commit 4affacb4e1 then inadvertently broke this for frameless windows. --- shell/browser/native_window.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/shell/browser/native_window.cc b/shell/browser/native_window.cc index f15c6556b2521..58457105cbfdf 100644 --- a/shell/browser/native_window.cc +++ b/shell/browser/native_window.cc @@ -154,7 +154,15 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) { } if (int x, y; options.Get(options::kX, &x) && options.Get(options::kY, &y)) { - SetPosition(gfx::Point{x, y}); + // BrightSign: Use SetBounds with the full rect (including width/height + // from options) instead of just SetPosition. CenterWindow in the + // NativeWindowViews constructor clamps the window size to the primary + // display's work area, which breaks windows spanning multiple displays + // (e.g. dual HDMI at 3840x1080). SetPosition only restores the origin + // and preserves the clamped size, so we must restore the full bounds. + const int w = options.ValueOrDefault(options::kWidth, GetSize().width()); + const int h = options.ValueOrDefault(options::kHeight, GetSize().height()); + SetBounds(gfx::Rect(x, y, w, h), false); #if BUILDFLAG(IS_WIN) // FIXME(felixrieseberg): Dirty, dirty workaround for