Bug 1799394 - Make dialog sizing code consistent between C++ and JS. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D161429
This commit is contained in:
Emilio Cobos Álvarez 2022-11-11 10:08:56 +00:00
Родитель bfb8b1296e
Коммит 00750e17e2
4 изменённых файлов: 60 добавлений и 23 удалений

Просмотреть файл

@ -196,6 +196,8 @@
return this.shadowRoot.querySelector(".dialog-button-box");
}
// NOTE(emilio): This has to match AppWindow::IntrinsicallySizeShell, to
// prevent flickering, see bug 1799394.
_sizeToPreferredSize() {
const docEl = document.documentElement;
const prefWidth = (() => {

Просмотреть файл

@ -1012,9 +1012,10 @@ STATIC_ATOMS = [
Atom("prefersReducedMotion", "prefers-reduced-motion"),
Atom("prefersColorScheme", "prefers-color-scheme"),
Atom("prefersContrast", "prefers-contrast"),
Atom("prefix", "prefix"),
Atom("prefwidth", "prefwidth"),
Atom("dynamicRange", "dynamic-range"),
Atom("videoDynamicRange", "video-dynamic-range"),
Atom("prefix", "prefix"),
Atom("preload", "preload"),
Atom("preserve", "preserve"),
Atom("preserveSpace", "preserve-space"),

Просмотреть файл

@ -2598,6 +2598,55 @@ void AppWindow::LoadPersistentWindowState() {
loadValue(nsGkAtoms::sizemode);
}
void AppWindow::IntrinsicallySizeShell(const CSSIntSize& aWindowDiff,
int32_t& aSpecWidth,
int32_t& aSpecHeight) {
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
if (!cv) {
return;
}
RefPtr<nsDocShell> docShell = mDocShell;
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
if (!treeOwner) {
return;
}
CSSIntCoord maxWidth = 0;
CSSIntCoord maxHeight = 0;
CSSIntCoord prefWidth = 0;
if (RefPtr element = GetWindowDOMElement()) {
nsAutoString prefWidthAttr;
if (element->GetAttr(nsGkAtoms::prefwidth, prefWidthAttr)) {
// TODO: Make this more generic perhaps?
if (prefWidthAttr.EqualsLiteral("min-width")) {
if (auto* f = element->GetPrimaryFrame(FlushType::Frames)) {
const auto& coord = f->StylePosition()->mMinWidth;
if (coord.ConvertsToLength()) {
prefWidth = CSSPixel::FromAppUnitsRounded(coord.ToLength());
}
}
}
}
}
Maybe<CSSIntSize> size = cv->GetContentSize(maxWidth, maxHeight, prefWidth);
if (!size) {
return;
}
nsPresContext* pc = cv->GetPresContext();
MOZ_ASSERT(pc, "Should have pres context");
int32_t width = pc->CSSPixelsToDevPixels(size->width);
int32_t height = pc->CSSPixelsToDevPixels(size->height);
treeOwner->SizeShellTo(docShell, width, height);
// Update specified size for the final LoadPositionFromXUL call.
aSpecWidth = size->width + aWindowDiff.width;
aSpecHeight = size->height + aWindowDiff.height;
}
void AppWindow::SizeShell() {
AutoRestore<bool> sizingShellFromXUL(mSizingShellFromXUL);
mSizingShellFromXUL = true;
@ -2610,7 +2659,7 @@ void AppWindow::SizeShell() {
windowElement->GetAttr(nsGkAtoms::windowtype, windowType);
}
CSSIntSize windowDiff = GetOuterToInnerSizeDifferenceInCSSPixels(
const CSSIntSize windowDiff = GetOuterToInnerSizeDifferenceInCSSPixels(
mWindow, UnscaledDevicePixelsPerCSSPixel());
// If we're using fingerprint resistance, we're going to resize the window
@ -2652,28 +2701,9 @@ void AppWindow::SizeShell() {
SetSpecifiedSize(specWidth, specHeight);
}
// If LoadSizeFromXUL set the size, mIntrinsicallySized will be false.
if (mIntrinsicallySized) {
// (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
if (cv) {
RefPtr<nsDocShell> docShell = mDocShell;
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
if (treeOwner) {
if (Maybe<CSSIntSize> size = cv->GetContentSize()) {
nsPresContext* pc = cv->GetPresContext();
MOZ_ASSERT(pc, "Should have pres context");
int32_t width = pc->CSSPixelsToDevPixels(size->width);
int32_t height = pc->CSSPixelsToDevPixels(size->height);
treeOwner->SizeShellTo(docShell, width, height);
// Update specified size for the final LoadPositionFromXUL call.
specWidth = width + windowDiff.width;
specHeight = height + windowDiff.height;
}
}
}
IntrinsicallySizeShell(windowDiff, specWidth, specHeight);
}
// Now that we have set the window's final size, we can re-do its

Просмотреть файл

@ -374,6 +374,10 @@ class AppWindow final : public nsIBaseWindow,
WidgetListenerDelegate mWidgetListenerDelegate;
private:
MOZ_CAN_RUN_SCRIPT void IntrinsicallySizeShell(const CSSIntSize& aWindowDiff,
int32_t& aSpecWidth,
int32_t& aSpecHeight);
// GetPrimaryBrowserParentSize is called from xpidl methods and we don't have
// a good way to annotate those with MOZ_CAN_RUN_SCRIPT yet. It takes no
// refcounted args other than "this", and the "this" uses seem ok.