Closed
Bug 1446343
Opened 7 years ago
Closed 7 years ago
Session restore does not preserve dimensions of minimized windows
Categories
(Firefox :: Session Restore, defect)
Tracking
()
VERIFIED
FIXED
Firefox 61
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox59 | --- | unaffected |
firefox60 | --- | verified |
firefox61 | --- | verified |
People
(Reporter: benmullins+github, Assigned: xidorn)
References
Details
(Keywords: regression)
Attachments
(2 files)
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Build ID: 20180315223216
Steps to reproduce:
1. Starting with at least two windows open, minimize one.
2. Exit Firefox from the menu.
3. Launch Firefox. Restore the previous session.
Actual results:
The minimized window is restored at a smaller size than it was when Firefox was closed.
Expected results:
The minimized window should be restored with the original dimensions it had.
---
I can reproduce this bug on the beta (60b) and nightly (61a) branches on Windows 10. I was not able to reproduce this bug on stable (59). I was not able to reproduce this bug on any version of Firefox in Linux.
I noticed the window that I sometimes have minimized started exhibiting this behavior perhaps a couple weeks ago, but didn't work out the exact nature of the bug until now. For most of the 60a release cycle of Nightly this did not occur.
Reporter | ||
Updated•7 years ago
|
Comment 1•7 years ago
|
||
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Firefox: 61.0a1, Build ID: 20180321102906
I have managed to reproduce this issue on latest Beta (60.0b5)and latest Nightly (60.a1) build. The issue is also reproducible if you restart the browser using the "restart" command in Developer Toolbar (F12).
I have managed to reproduce the issue on Windows 7 x64, Windows 10 x64 and Mac 10.12 but I haven't manage to reproduce it on Arch Linux.
Indeed the issue is not reproducible on latest Firefox (59.0.1) release. Considering this I have used the mozregression tools and I have found the regression range. Here are the results:
Last good revision: 5ceb1365ae756eabe0763de42cb64fd9dc3e79dc
First bad revision: 7d40106bafebdd868ca7f6d188b5f0e30cb6f0e3
Pushlog: https://goo.gl/dk4VGv
From the provided pushlog, looks like bug 1442521 introduce the issue.
Xidorn can you please take a look at this?
Blocks: 1442521
Status: UNCONFIRMED → NEW
status-firefox59:
--- → unaffected
status-firefox60:
--- → affected
status-firefox61:
--- → affected
Component: Untriaged → XUL
Ever confirmed: true
Flags: needinfo?(xidorn+moz)
OS: Windows 10 → All
Product: Firefox → Core
Assignee | ||
Comment 2•7 years ago
|
||
It is expected that bug 1442521 doesn't affect linux because on linux the outer size and inner size are identical (we don't count window decoration in the outer size, unlike on other systems).
Sounds like the inner sizes are incorrectly applied as outer size somehow.
Assignee | ||
Comment 3•7 years ago
|
||
Since widget code is very tricky to fix (as shown with my recent experience), I'd actually prefer we just backout bug 1442521 from 60beta, and we can continue fixing the regressions from that in 61.
Given that we decided not to uplift bug 1439875 to 60, there is no need for that patch to stay there.
Comment 4•7 years ago
|
||
Fixed by backout for Fx60.
Assignee | ||
Comment 5•7 years ago
|
||
I can reproduce this on Windows. This is probably that there is some inconsistency in session store component.
I inspected a sessionstore file, and it turns out it saves different size for window minimized. Snippets below:
> "windows": [
> {
> // ...
> "busy": false,
> "width": 1296,
> "height": 1079,
> "screenX": 4,
> "screenY": 40,
> "sizemode": "normal"
> },
> {
> // ...
> "busy": false,
> "width": "1280",
> "height": "1040",
> "screenX": "8",
> "screenY": "41",
> "sizemode": "minimized"
> }
> ],
These two windows ought to have the same size, but they are serialized to different sizes. Interestingly, they use different types (normal uses numbers, while minimized one uses strings).
So this is probably related to where session store reads the information from.
Leave the ni? and I'll continue investigating.
Component: XUL → Session Restore
Product: Core → Firefox
Assignee | ||
Comment 6•7 years ago
|
||
So... the related code is SessionStoreInternal._getWindowDimension[1]. It tries to query the window outer size, but instead uses attributes on document element when the sizemode is not normal.
And this is regressed by bug 1442521 because the meaning of attributes on document element was changed there.
We've handled similar situation in bug 1444525 for XUL persistence, and probably we need to do something alike for session store.
[1] https://searchfox.org/mozilla-central/rev/d0413b711da4dac72b237d0895daba2537f1514c/browser/components/sessionstore/SessionStore.jsm#4333-4363
See Also: → 1444525
Assignee | ||
Comment 7•7 years ago
|
||
I have some idea.
Assignee: nobody → xidorn+moz
Flags: needinfo?(xidorn+moz)
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
![]() |
||
Comment 10•7 years ago
|
||
mozreview-review |
Comment on attachment 8965557 [details]
Bug 1446343 part 1 - Expose GetOuterToInner{Width,Height}DifferenceInCSSPixels to script.
https://reviewboard.mozilla.org/r/234350/#review239972
::: xpfe/appshell/nsIXULWindow.idl:73
(Diff revision 1)
> - [noscript,notxpcom] uint32_t getOuterToInnerHeightDifferenceInCSSPixels();
> - [noscript,notxpcom] uint32_t getOuterToInnerWidthDifferenceInCSSPixels();
> + uint32_t getOuterToInnerHeightDifferenceInCSSPixels();
> + uint32_t getOuterToInnerWidthDifferenceInCSSPixels();
If you make these [infallible] readonly attributes, you can at least keep calling the nicer signatures in C++...
Attachment #8965557 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 11•7 years ago
|
||
Seems macOS will fail the screen{X,Y} test... Let's just check width and height for now :/
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Updated•7 years ago
|
Attachment #8965557 -
Flags: review+ → review?(bzbarsky)
Comment 14•7 years ago
|
||
mozreview-review |
Comment on attachment 8965558 [details]
Bug 1446343 part 2 - Convert size attributes to outer size for sessionstore.
https://reviewboard.mozilla.org/r/234352/#review240052
Very close, hence the r- :) Thanks for fixing this!
This new test is failing on OSX, so you probably want to check out why that is. (On OSX, 'maximize' is basically Fullscreen mode on OSX with a transition and 'minimize' transitions as well, which might influence the values after the 'sizemodechange' event fires.)
::: browser/components/sessionstore/SessionStore.jsm:4347
(Diff revision 2)
> return "normal";
> }
> }
>
> - var dimension;
> + // If the sizemode is not normal, their dimension may be misleading,
> + // so try to read from the attribute first.
nit: Can you spend a few words here to explain _why_ it may be misleading, or point to a bug/ documentation that'd explain it in more detail. Because I'm having difficulty understand the _why_ we need to jump through hoops like this in frontend code already :-(
::: browser/components/sessionstore/SessionStore.jsm:4355
(Diff revision 2)
> + let attr = parseInt(docElem.getAttribute(aAttribute), 10);
> + if (attr) {
> + if (aAttribute != "width" && aAttribute != "height") {
> + return attr;
> + }
> + // width and height attribute are inner size, but we want to
nit: "Width and height attributes report the inner size,"
::: browser/components/sessionstore/SessionStore.jsm:4361
(Diff revision 2)
> + // store the outer size, so add the difference.
> + let xulWin = aWindow.getInterface(Ci.nsIDocShell)
> + .treeOwner
> + .QueryInterface(Ci.nsIInterfaceRequestor)
> + .getInterface(Ci.nsIXULWindow);
> + let diff = aAttribute == "width"
Perhaps it'd be nice to shorten this to:
```js
return attr + xulWin[`outerToInner${aAttribute.charAt(0).toUpperCase() + aAttribute.substr(1)}DifferenceInCSSPixels`];
```
or
```js
return attr + xulWin[`outerToInner${aAttribute == "width" ? "Width" : "Height"}DifferenceInCSSPixels`];
```
?
::: browser/components/sessionstore/SessionStore.jsm:4371
(Diff revision 2)
> + }
> +
> + let dimension;
> switch (aAttribute) {
> case "width":
> dimension = aWindow.outerWidth;
We might as return the values from inside the `switch` statement and skip storing it in a temp variable.
::: browser/components/sessionstore/test/browser_1446343-windowsize.js:4
(Diff revision 2)
> +add_task(async function test() {
> + const win = await BrowserTestUtils.openNewBrowserWindow();
> + registerCleanupFunction(function() {
> + BrowserTestUtils.closeWindow(win);
Instead of using `registerCleanupFunction`, can you move `await BrowserTestUtils.closeWindow(win)` to the end of this function?
::: browser/components/sessionstore/test/browser_1446343-windowsize.js:21
(Diff revision 2)
> + const {outerWidth, outerHeight} = win;
> + function checkCurrentState(sizemode) {
> + let state = JSON.parse(ss.getWindowState(win));
> + let winState = state.windows[0];
> + let msgSuffix = ` should match on ${sizemode} mode`;
> + is(winState.width, outerWidth, "width" + msgSuffix);
nit: Can you use `Assert.equal` here?
Attachment #8965558 -
Flags: review-
Assignee | ||
Comment 15•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8965558 [details]
Bug 1446343 part 2 - Convert size attributes to outer size for sessionstore.
https://reviewboard.mozilla.org/r/234352/#review240052
That may be done in a separate bug, because I don't think they are related to this bug. If you want, I can keep the test and make them conditionally expected fail for macOS.
> nit: Can you spend a few words here to explain _why_ it may be misleading, or point to a bug/ documentation that'd explain it in more detail. Because I'm having difficulty understand the _why_ we need to jump through hoops like this in frontend code already :-(
This is existing logic, which I just expand a bit...
Basically, we want to persist the size / position in normal state, because even if the window is maximized / minimized, user may still want to restore them to the size it was previously.
The attributes on window object are for the current state, and thus not the size / position we want the window to restore to. In that case, we assume that the corresponding attributes on the root element has the values we want.
> Perhaps it'd be nice to shorten this to:
> ```js
> return attr + xulWin[`outerToInner${aAttribute.charAt(0).toUpperCase() + aAttribute.substr(1)}DifferenceInCSSPixels`];
> ```
>
> or
>
> ```js
> return attr + xulWin[`outerToInner${aAttribute == "width" ? "Width" : "Height"}DifferenceInCSSPixels`];
> ```
> ?
I... don't really think it is more readable than a simple ternary expression...
> Instead of using `registerCleanupFunction`, can you move `await BrowserTestUtils.closeWindow(win)` to the end of this function?
I believe `registerCleanupFunction` is more robust, in the sense that even if there is any exception happens inside the test, the window would still be closed properly.
Also, having the cleanup code closer to the initialization code may make stuff easier to reason about.
> nit: Can you use `Assert.equal` here?
How is this different from `is`? How can I express `todo_is` with `Assert` (for macOS `screenX` and `screenY` in case you want)?
Updated•7 years ago
|
Attachment #8965558 -
Flags: review?(dao+bmo)
Comment 16•7 years ago
|
||
(In reply to Xidorn Quan [:xidorn] UTC+10 from comment #15)
> That may be done in a separate bug, because I don't think they are related
> to this bug. If you want, I can keep the test and make them conditionally
> expected fail for macOS.
Sure, but since you're introducing the test file in this bug and land it whilst perma-failing on OSX, you'll get backed out for sure... that's basically why I made the remark. Please feel free to skip the assertions on OSX.
> This is existing logic, which I just expand a bit...
>
> Basically, we want to persist the size / position in normal state, because
> even if the window is maximized / minimized, user may still want to restore
> them to the size it was previously.
>
> The attributes on window object are for the current state, and thus not the
> size / position we want the window to restore to. In that case, we assume
> that the corresponding attributes on the root element has the values we want.
I understand now :) It'd be real nice to have this explanation near the code as well!
> I... don't really think it is more readable than a simple ternary
> expression...
Up to you, really, that's why I noted it as a nit (I believe).
> I believe `registerCleanupFunction` is more robust, in the sense that even
> if there is any exception happens inside the test, the window would still be
> closed properly.
>
> Also, having the cleanup code closer to the initialization code may make
> stuff easier to reason about.
If there's an exception thrown inside the test, we'd be in trouble anyways, so a leaking window will be the least of our worries.
In new tests we basically shy away from `registerCleanupFunction` and use the more linear approach, i.e. without the branching with callbacks. The async...await style has simplified the code flow in tests considerably that they're much more readable, thus having a cleanup phase at the end is quite easy to reason about.
> How is this different from `is`? How can I express `todo_is` with `Assert`
> (for macOS `screenX` and `screenY` in case you want)?
It's not different at all, only stylistic. This means that it's up to you what you prefer. I made it so that `is()` uses Assert.jsm under the hood anyway.
There's no 'todo' functionality in the Assert namespace, so you won't be able to. But I'm not a fan of todo's in code regardless, because they tend to never get resolved. In these cases I prefer to handle exceptions as:
```js
if (AppConstants.platform != "macosx") {
//...
}
```
Assignee | ||
Comment 17•7 years ago
|
||
(In reply to Mike de Boer [:mikedeboer] (Back! Processing backlog...) from comment #16)
> > How is this different from `is`? How can I express `todo_is` with `Assert`
> > (for macOS `screenX` and `screenY` in case you want)?
>
> It's not different at all, only stylistic. This means that it's up to you
> what you prefer. I made it so that `is()` uses Assert.jsm under the hood
> anyway.
> There's no 'todo' functionality in the Assert namespace, so you won't be
> able to. But I'm not a fan of todo's in code regardless, because they tend
> to never get resolved. In these cases I prefer to handle exceptions as:
I believe part of the value of 'todo' is that, when it is accidently fixed by someone else, we can catch that on the CI and start enforcing it.
Comment hidden (mozreview-request) |
Comment 19•7 years ago
|
||
mozreview-review |
Comment on attachment 8965558 [details]
Bug 1446343 part 2 - Convert size attributes to outer size for sessionstore.
https://reviewboard.mozilla.org/r/234352/#review240098
Thanks!
Attachment #8965558 -
Flags: review?(mdeboer) → review+
Assignee | ||
Comment 20•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8965558 [details]
Bug 1446343 part 2 - Convert size attributes to outer size for sessionstore.
https://reviewboard.mozilla.org/r/234352/#review240098
Thanks for the quick review!
![]() |
||
Comment 21•7 years ago
|
||
mozreview-review |
Comment on attachment 8965557 [details]
Bug 1446343 part 1 - Expose GetOuterToInner{Width,Height}DifferenceInCSSPixels to script.
https://reviewboard.mozilla.org/r/234350/#review240258
Attachment #8965557 -
Flags: review?(bzbarsky) → review+
Comment 22•7 years ago
|
||
Pushed by xquan@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/aa7d70282996
part 1 - Expose GetOuterToInner{Width,Height}DifferenceInCSSPixels to script. r=bz
https://hg.mozilla.org/integration/autoland/rev/ba7856d07da4
part 2 - Convert size attributes to outer size for sessionstore. r=mikedeboer
Comment 23•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/aa7d70282996
https://hg.mozilla.org/mozilla-central/rev/ba7856d07da4
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 61
Updated•7 years ago
|
status-firefox-esr52:
--- → unaffected
Comment 24•7 years ago
|
||
This issue is no longer reproducible on either Firefox 60.0b16 (20180426170554) on Windows 10x64 or on Firefox Nightly 61.0a1 (20180503220110) on Windows 10x64.
[bugday-20180502]
Comment 25•7 years ago
|
||
(In reply to Tom Bannister from comment #24)
> This issue is no longer reproducible on either Firefox 60.0b16
> (20180426170554) on Windows 10x64 or on Firefox Nightly 61.0a1
> (20180503220110) on Windows 10x64.
>
> [bugday-20180502]
Thanks for verifying this issue. Marking accordingly.
Updated•7 years ago
|
Flags: in-qa-testsuite+
You need to log in
before you can comment on or make changes to this bug.
Description
•