Bug 1814834 - Maintain client size in SyncAttributesToWidget() depending on the last resize. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D169633
This commit is contained in:
Matthias Camenzind 2023-02-13 21:00:02 +00:00
parent e1e71f371c
commit a36aa2e14f
3 changed files with 24 additions and 18 deletions

View File

@ -108,24 +108,7 @@ async function runTest(aWindow) {
// Open a new window with size specified.
win = openWindow("width=400,height=400");
await SimpleTest.promiseFocus(win);
// TODO(bug 1814834): This fails on Windows/macOS when there's no titlebar.
// This is because by the time we size the window there isn't a root element
// yet, so we can't see that the sizemode will be zero and we size as-if
// there was a titlebar. Maybe we should delay the resizes until the chrome
// loads or something?
if (gTitlebar || isLinux) {
checkWindow("when reopen with size", win, win.STATE_NORMAL, 400, 400);
} else {
let w = win.innerWidth;
let h = win.innerHeight;
ok(w >= 400, `Should have enough width ${w}`);
ok(h >= 400, `Should have enough height ${h}`);
todo(
w == 400 && h == 400,
`Should have exactly the right size (${w}x${h} != 400x400)`
);
checkWindow("when reopen with size", win, win.STATE_NORMAL, w, h);
}
checkWindow("when reopen with size", win, win.STATE_NORMAL, 400, 400);
await waitForSizeModePersisted();
win.close();

View File

@ -127,6 +127,7 @@ AppWindow::AppWindow(uint32_t aChromeFlags)
mIgnoreXULSizeMode(false),
mDestroying(false),
mRegistered(false),
mDominantClientSize(false),
mChromeFlags(aChromeFlags),
mWidgetListenerDelegate(this) {}
@ -770,6 +771,7 @@ nsresult AppWindow::MoveResize(const Maybe<DesktopPoint>& aPosition,
if (aSize) {
mWindow->SetSizeMode(nsSizeMode_Normal);
mIntrinsicallySized = false;
mDominantClientSize = false;
}
if (aPosition && aSize) {
@ -1601,6 +1603,13 @@ void AppWindow::SyncAttributesToWidget() {
nsAutoString attr;
// Some attributes can change the client size (e.g. chromemargin on Windows
// and MacOS). But we might want to keep it.
const LayoutDeviceIntSize oldClientSize = mWindow->GetClientSize();
// We have to check now whether we want to restore the client size, as any
// change in size will reset its state.
bool maintainClientSize = mDominantClientSize;
// "hidechrome" attribute
if (windowElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidechrome,
nsGkAtoms::_true, eCaseMatters)) {
@ -1658,6 +1667,14 @@ void AppWindow::SyncAttributesToWidget() {
if (attr.EqualsLiteral("document")) {
mWindow->SetWindowAnimationType(nsIWidget::eDocumentWindowAnimation);
}
// Check if the client size did change and if we want to restore it.
if (maintainClientSize && mWindow->SizeMode() == nsSizeMode_Normal &&
oldClientSize != mWindow->GetClientSize()) {
mWindow->ResizeClient(oldClientSize / mWindow->GetDesktopToDeviceScale(),
true);
mDominantClientSize = true;
}
}
enum class ConversionDirection {
@ -2226,6 +2243,7 @@ NS_IMETHODIMP AppWindow::SizeShellTo(nsIDocShellTreeItem* aShellItem,
auto newSize =
LayoutDeviceIntSize(aCX, aCY) + GetOuterToInnerSizeDifference(mWindow);
SetSize(newSize.width, newSize.height, /* aRepaint = */ true);
mDominantClientSize = true;
return NS_OK;
}
@ -2771,6 +2789,7 @@ void AppWindow::SizeShellToWithLimit(int32_t aDesiredWidth,
// has yet to complete can still change the size. We want the latest call to
// define the final size.
SetSize(winWidth, winHeight, true);
mDominantClientSize = true;
}
nsresult AppWindow::GetTabCount(uint32_t* aResult) {
@ -2821,6 +2840,7 @@ bool AppWindow::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) {
bool AppWindow::WindowResized(nsIWidget* aWidget, int32_t aWidth,
int32_t aHeight) {
mDominantClientSize = false;
if (mDocShell) {
mDocShell->SetPositionAndSize(0, 0, aWidth, aHeight, 0);
}

View File

@ -356,6 +356,9 @@ class AppWindow final : public nsIBaseWindow,
// otherwise happen due to script running as we tear down various things.
bool mDestroying;
bool mRegistered;
// Indicator for whether the client size, instead of the window size, should
// be maintained in case of a change in their relation.
bool mDominantClientSize;
PersistentAttributes mPersistentAttributesDirty;
PersistentAttributes mPersistentAttributesMask;
uint32_t mChromeFlags;