From 85cc23d7c2c3427718afa4be91017794597b2767 Mon Sep 17 00:00:00 2001 From: Miguel Palau Zarza Date: Thu, 7 May 2026 13:31:27 -0600 Subject: [PATCH 1/4] gh-13518: Fix oversized extension popup panel on Wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Browser-action extension popups (which use `ViewPopup` with `fixedWidth=false`) rely on `viewNode.customRectGetter` to tell panelmultiview how tall the subview should be: this.viewNode.customRectGetter = () => { return { height: this.lastCalculatedInViewHeight || this.viewHeight }; }; `resizeBrowser` already updates `lastCalculatedInViewHeight` in the `fixedWidth=true` branch but forgets to do it in the `fixedWidth=false` branch (which is what `browser_action` popups always use). As a result `customRectGetter` keeps returning the stale `viewHeight` that was captured once during `attach()` from `viewNode.getBoundingClientRect().height`. On Wayland compositors with fractional scaling (e.g. Hyprland), and especially in single-toolbar layouts where the panelview is reparented into a freshly created `customizationui-widget-panel`, that one-shot measurement can land on an inflated value before the popup HTML reports its real intrinsic size. The inner `` ends up sized correctly, but the surrounding panel stays locked to the inflated height — which shows up to the user as a small popup floating in a tall, mostly-empty panel, with the bottom of the popup unclickable. Mirror the existing `fixedWidth=true` update in the `else` branch so `customRectGetter` always reports the up-to-date popup height and panelmultiview lets the panel shrink to fit. Ships as a temporary external Firefox patch under `src/external-patches/firefox/` until it lands upstream in Mozilla. --- ...h-13518_extension_popup_resize_panel.patch | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch diff --git a/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch b/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch new file mode 100644 index 0000000000..0e6f36285a --- /dev/null +++ b/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch @@ -0,0 +1,49 @@ +# See https://github.com/zen-browser/desktop/issues/13518 +# +# Browser-action extension popups (which use ViewPopup with fixedWidth=false) +# rely on `viewNode.customRectGetter` to tell panelmultiview how tall the +# subview should be: +# +# this.viewNode.customRectGetter = () => { +# return { height: this.lastCalculatedInViewHeight || this.viewHeight }; +# }; +# +# `viewHeight` is captured once during `attach()` from +# `viewNode.getBoundingClientRect().height`. On Wayland compositors with +# fractional scaling (e.g. Hyprland), and in Zen's single-toolbar layouts where +# the panelview is reparented into a freshly created `customizationui-widget- +# panel`, that one-shot measurement can land on an inflated value before the +# popup HTML reports its real intrinsic size. After that, the popup browser +# itself is resized correctly via `resizeBrowser`, but the surrounding panel +# never shrinks because `customRectGetter` keeps returning the stale +# `viewHeight`. The result is a small popup floating in a tall, mostly-empty +# panel, with the bottom of the popup unclickable. +# +# `resizeBrowser` already updates `lastCalculatedInViewHeight` for the +# `fixedWidth=true` branch but forgets to do it for the `fixedWidth=false` +# branch (which is the default for `browser_action` popups). Mirror that same +# update so `customRectGetter` always reports the up-to-date popup height and +# panelmultiview lets the panel shrink to fit. +# +# This is a temporary external patch. Once it lands upstream in Firefox the +# corresponding section of this patch will start failing to apply and the +# patch should be removed (per src/external-patches/firefox/README.md). +diff --git a/browser/components/extensions/ExtensionPopups.sys.mjs b/browser/components/extensions/ExtensionPopups.sys.mjs +--- a/browser/components/extensions/ExtensionPopups.sys.mjs ++++ b/browser/components/extensions/ExtensionPopups.sys.mjs +@@ -416,10 +416,15 @@ + } else { + this.browser.style.width = `${width}px`; + this.browser.style.minWidth = `${width}px`; + this.browser.style.height = `${height}px`; + this.browser.style.minHeight = `${height}px`; ++ ++ // Mirror the fixedWidth branch so `customRectGetter` reports the ++ // up-to-date popup height instead of the stale `viewHeight` that was ++ // captured once during `attach()`. See gh-13518. ++ this.lastCalculatedInViewHeight = height; + } + + let event = new this.window.CustomEvent("WebExtPopupResized", { detail }); + this.browser.dispatchEvent(event); + } From a27cf7c5b5d209d9afbe2a5fa254408271aa75cd Mon Sep 17 00:00:00 2001 From: Miguel Palau Zarza Date: Thu, 7 May 2026 17:53:42 -0600 Subject: [PATCH 2/4] fix: update lastCalculatedInViewHeight in fixedWidth=false branch --- ...h-13518_extension_popup_resize_panel.patch | 38 ++----------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch b/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch index 0e6f36285a..9337f9e3da 100644 --- a/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch +++ b/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch @@ -1,46 +1,16 @@ -# See https://github.com/zen-browser/desktop/issues/13518 -# -# Browser-action extension popups (which use ViewPopup with fixedWidth=false) -# rely on `viewNode.customRectGetter` to tell panelmultiview how tall the -# subview should be: -# -# this.viewNode.customRectGetter = () => { -# return { height: this.lastCalculatedInViewHeight || this.viewHeight }; -# }; -# -# `viewHeight` is captured once during `attach()` from -# `viewNode.getBoundingClientRect().height`. On Wayland compositors with -# fractional scaling (e.g. Hyprland), and in Zen's single-toolbar layouts where -# the panelview is reparented into a freshly created `customizationui-widget- -# panel`, that one-shot measurement can land on an inflated value before the -# popup HTML reports its real intrinsic size. After that, the popup browser -# itself is resized correctly via `resizeBrowser`, but the surrounding panel -# never shrinks because `customRectGetter` keeps returning the stale -# `viewHeight`. The result is a small popup floating in a tall, mostly-empty -# panel, with the bottom of the popup unclickable. -# -# `resizeBrowser` already updates `lastCalculatedInViewHeight` for the -# `fixedWidth=true` branch but forgets to do it for the `fixedWidth=false` -# branch (which is the default for `browser_action` popups). Mirror that same -# update so `customRectGetter` always reports the up-to-date popup height and -# panelmultiview lets the panel shrink to fit. -# -# This is a temporary external patch. Once it lands upstream in Firefox the -# corresponding section of this patch will start failing to apply and the -# patch should be removed (per src/external-patches/firefox/README.md). +# https://github.com/zen-browser/desktop/issues/13518 +# Update `lastCalculatedInViewHeight` in the fixedWidth=false branch of +# `resizeBrowser` so the panel shrinks to the actual popup height. diff --git a/browser/components/extensions/ExtensionPopups.sys.mjs b/browser/components/extensions/ExtensionPopups.sys.mjs --- a/browser/components/extensions/ExtensionPopups.sys.mjs +++ b/browser/components/extensions/ExtensionPopups.sys.mjs -@@ -416,10 +416,15 @@ +@@ -416,10 +416,12 @@ } else { this.browser.style.width = `${width}px`; this.browser.style.minWidth = `${width}px`; this.browser.style.height = `${height}px`; this.browser.style.minHeight = `${height}px`; + -+ // Mirror the fixedWidth branch so `customRectGetter` reports the -+ // up-to-date popup height instead of the stale `viewHeight` that was -+ // captured once during `attach()`. See gh-13518. + this.lastCalculatedInViewHeight = height; } From 46d1ed92981a6dad8a31dcf400683a6fff94f322 Mon Sep 17 00:00:00 2001 From: Miguel Palau Zarza Date: Thu, 14 May 2026 08:45:14 -0600 Subject: [PATCH 3/4] fix: regenerate extension popup patch via surfer export Replace the hand-written external patch with a properly exported patch generated by `npm run export`. Moves the patch from external-patches to the standard src/ patch directory. --- .../extensions/ExtensionPopups-sys-mjs.patch} | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) rename src/{external-patches/firefox/gh-13518_extension_popup_resize_panel.patch => browser/components/extensions/ExtensionPopups-sys-mjs.patch} (62%) diff --git a/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch b/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch similarity index 62% rename from src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch rename to src/browser/components/extensions/ExtensionPopups-sys-mjs.patch index 9337f9e3da..ba3016b831 100644 --- a/src/external-patches/firefox/gh-13518_extension_popup_resize_panel.patch +++ b/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch @@ -1,12 +1,8 @@ -# https://github.com/zen-browser/desktop/issues/13518 -# Update `lastCalculatedInViewHeight` in the fixedWidth=false branch of -# `resizeBrowser` so the panel shrinks to the actual popup height. diff --git a/browser/components/extensions/ExtensionPopups.sys.mjs b/browser/components/extensions/ExtensionPopups.sys.mjs +index 1cd35175507bd442aae6857e65015cfed00058e3..376377629e9732b292085ba94309e47cc53ee2ef 100644 --- a/browser/components/extensions/ExtensionPopups.sys.mjs +++ b/browser/components/extensions/ExtensionPopups.sys.mjs -@@ -416,10 +416,12 @@ - } else { - this.browser.style.width = `${width}px`; +@@ -418,6 +418,8 @@ export class BasePopup { this.browser.style.minWidth = `${width}px`; this.browser.style.height = `${height}px`; this.browser.style.minHeight = `${height}px`; @@ -15,5 +11,3 @@ diff --git a/browser/components/extensions/ExtensionPopups.sys.mjs b/browser/com } let event = new this.window.CustomEvent("WebExtPopupResized", { detail }); - this.browser.dispatchEvent(event); - } From a851b1bbb5473cff05a3558eb329ca7201a8a71e Mon Sep 17 00:00:00 2001 From: Miguel Palau Zarza Date: Thu, 14 May 2026 09:01:08 -0600 Subject: [PATCH 4/4] fix: use Math.max to mirror fixedWidth=true branch Use `Math.max(height, this.viewHeight)` instead of bare `height` to match the behavior of the fixedWidth=true branch exactly. --- .../components/extensions/ExtensionPopups-sys-mjs.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch b/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch index ba3016b831..350624bbcc 100644 --- a/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch +++ b/src/browser/components/extensions/ExtensionPopups-sys-mjs.patch @@ -1,5 +1,5 @@ diff --git a/browser/components/extensions/ExtensionPopups.sys.mjs b/browser/components/extensions/ExtensionPopups.sys.mjs -index 1cd35175507bd442aae6857e65015cfed00058e3..376377629e9732b292085ba94309e47cc53ee2ef 100644 +index 1cd35175507bd442aae6857e65015cfed00058e3..c7f9c5a4de05cfa476b89137798061ce36ef2f40 100644 --- a/browser/components/extensions/ExtensionPopups.sys.mjs +++ b/browser/components/extensions/ExtensionPopups.sys.mjs @@ -418,6 +418,8 @@ export class BasePopup { @@ -7,7 +7,7 @@ index 1cd35175507bd442aae6857e65015cfed00058e3..376377629e9732b292085ba94309e47c this.browser.style.height = `${height}px`; this.browser.style.minHeight = `${height}px`; + -+ this.lastCalculatedInViewHeight = height; ++ this.lastCalculatedInViewHeight = Math.max(height, this.viewHeight); } let event = new this.window.CustomEvent("WebExtPopupResized", { detail });