mirror of
https://github.com/zen-browser/desktop.git
synced 2026-03-29 11:51:51 +00:00
gh-12782: Fix app menu items cut off on small screens (macOS) (gh-12832)
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
This commit is contained in:
@@ -331,7 +331,31 @@ window.gZenUIManager = {
|
||||
this._popupTrackingElements.remove(element);
|
||||
},
|
||||
|
||||
// On macOS, the app menu panel is displayed as a native NSPopover which
|
||||
// silently clips content beyond the screen without informing Firefox's
|
||||
// layout engine. This makes bottom menu items unreachable by scrolling.
|
||||
// Setting max-height based on available screen space lets Firefox's layout
|
||||
// handle the constraint, enabling proper overflow scrolling.
|
||||
// See gh-12782
|
||||
_constrainNativePopoverHeight(panel) {
|
||||
if (panel.id !== "appMenu-popup") {
|
||||
return;
|
||||
}
|
||||
// NSPopover adds 13px of chrome on all sides (26px vertical total),
|
||||
// measured via Accessibility Inspector on macOS 26 (Tahoe).
|
||||
// Previous macOS versions have similar or smaller values, so this is a
|
||||
// conservative upper bound.
|
||||
const popoverChrome = 26;
|
||||
panel.style.maxHeight = `${window.screen.availHeight - popoverChrome}px`;
|
||||
},
|
||||
|
||||
onPopupShowing(showEvent) {
|
||||
if (
|
||||
AppConstants.platform === "macosx" &&
|
||||
Services.prefs.getBoolPref("widget.macos.native-context-menus", false)
|
||||
) {
|
||||
this._constrainNativePopoverHeight(showEvent.target);
|
||||
}
|
||||
for (const el of this._popupTrackingElements) {
|
||||
// target may be inside a shadow root, not directly under the element
|
||||
// we also ignore menus inside panels
|
||||
|
||||
@@ -9,6 +9,7 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
"glance/browser.toml",
|
||||
"live-folders/browser.toml",
|
||||
"pinned/browser.toml",
|
||||
"popover/browser.toml",
|
||||
"spaces/browser.toml",
|
||||
"split_view/browser.toml",
|
||||
"tabs/browser.toml",
|
||||
|
||||
12
src/zen/tests/popover/browser.toml
Normal file
12
src/zen/tests/popover/browser.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[DEFAULT]
|
||||
prefs = ["zen.view.mac.show-three-dot-menu=true"]
|
||||
|
||||
["browser_popover_height_constraint.js"]
|
||||
run-if = [
|
||||
"os == 'mac'", # gh-12782
|
||||
]
|
||||
prefs = ["widget.macos.native-context-menus=true"]
|
||||
59
src/zen/tests/popover/browser_popover_height_constraint.js
Normal file
59
src/zen/tests/popover/browser_popover_height_constraint.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the app menu panel respects available screen height when
|
||||
// constrained. Without the fix, the panel ignores the available screen
|
||||
// height and lets NSPopover silently clip the content.
|
||||
// See gh-12782
|
||||
|
||||
add_task(async function test_appmenu_respects_screen_constraint() {
|
||||
const panel = document.getElementById("appMenu-popup");
|
||||
ok(panel, "appMenu-popup panel should exist");
|
||||
|
||||
// Mock a very small screen
|
||||
const realAvailHeight = window.screen.availHeight;
|
||||
const realAvailTop = window.screen.availTop;
|
||||
Object.defineProperty(window.screen, "availHeight", {
|
||||
value: 400,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window.screen, "availTop", {
|
||||
value: 0,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
try {
|
||||
const popupShown = BrowserTestUtils.waitForEvent(panel, "popupshown");
|
||||
PanelUI.toggle({ type: "command" });
|
||||
await popupShown;
|
||||
await new Promise(requestAnimationFrame);
|
||||
|
||||
const scrollBody = panel.querySelector(".panel-subview-body");
|
||||
ok(scrollBody, "Panel should have a scrollable body");
|
||||
|
||||
// With the fix, the panel content should be constrained to fit
|
||||
// within the mocked screen height. Without the fix, the body
|
||||
// will be sized to the real screen height (~639px), ignoring
|
||||
// the available screen constraint.
|
||||
ok(
|
||||
scrollBody.clientHeight < 450,
|
||||
`Scroll body height (${scrollBody.clientHeight}) should be constrained ` +
|
||||
`to fit within available screen height (400), not the real screen`
|
||||
);
|
||||
|
||||
const popupHidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
|
||||
PanelUI.toggle({ type: "command" });
|
||||
await popupHidden;
|
||||
} finally {
|
||||
Object.defineProperty(window.screen, "availHeight", {
|
||||
value: realAvailHeight,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window.screen, "availTop", {
|
||||
value: realAvailTop,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user