Closed
Bug 838239
Opened 13 years ago
Closed 12 years ago
[hidpi] wrong devicePixelRatio in browser history
Categories
(Core :: Widget: Cocoa, defect)
Tracking
()
VERIFIED
FIXED
mozilla23
People
(Reporter: chrille_b, Assigned: jfkthame)
References
(Blocks 1 open bug)
Details
(Keywords: regression)
Attachments
(1 file, 3 obsolete files)
1.86 KB,
patch
|
roc
:
review+
smichaud
:
feedback+
bajaj
:
approval-mozilla-aurora+
bajaj
:
approval-mozilla-beta+
|
Details | Diff | Splinter Review |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0) Gecko/20130114 Firefox/20.0
Build ID: 20130114042016
Steps to reproduce:
Use mixed lo/hi-dpi screens with a macbook retina.
Open firefox on a hi-dpi screen.
Open a website (e.g. www.google.com) and search for something or click on a link.
Move firefox window to a lo-dpi screen.
Click on the back button.
Actual results:
The window has the wrong devicePixelRatio. It has the value of 2 (which was the value of my hi-dpi screen when the page was loaded at that screen).
This happens on firefox 20+ (Aurora and Nightly).
Expected results:
devicePixelRatio should have a value of 1.
Updated•13 years ago
|
Component: Untriaged → Widget: Cocoa
Product: Firefox → Core
Assignee | ||
Comment 1•13 years ago
|
||
The reverse case (moving the window from lo-dpi to hi-dpi and then stepping back through history) also shows incorrect scaling.
Oddly, not -all- pages exhibit the problem; sometimes <back> gives me a properly-scaled page, but then going back another step may produces the incorrect scaling.
Anyway, there's definitely a problem here; it looks like when we restore content from the bfcache to the window, we don't check/update the pix ratio as needed.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Version: 20 Branch → Trunk
Comment 2•12 years ago
|
||
Jonathan asked me for help with this while he was otherwise occupied, last week. He pointed out that it'd be logical to call nsIPresShell::BackingScaleFactorChanged() from nsDocShell::RestoreFromHistory(), but that more seems to be needed.
I banged my head against this for a few days, last week and this week, and I think I've now come up with the answer.
The reason why a simple call to nsIPresShell::BackingScaleFactorChanged() didn't work is that the nsDocShell in question always corresponds to an nsChildView widget (i.e. to an nsView), not to an nsCocoaWindow widget (i.e. an nsWebShellWindow). But if the backing scale factor of one needs to be updated, so does the other.
(Calls to BackingScaleFactorChanged() from widget code always happen for both kinds of object at the same time. So we don't have to worry about this when, say, the user drags a window from a Retina display to a non-Retina display.)
Assignee: nobody → smichaud
Comment 3•12 years ago
|
||
Jonathan, what do you think of this patch?
I suppose I should ask Roc to review it, but I'd like to get your opinion first.
In my tests it seems to do the trick. I'm about to start a tryserver build, which (along with the test results) should be available in a few hours ... or at least by tomorrow morning.
Attachment #716848 -
Flags: feedback?(jfkthame)
Assignee | ||
Comment 4•12 years ago
|
||
Comment on attachment 716848 [details] [diff] [review]
Fix
Review of attachment 716848 [details] [diff] [review]:
-----------------------------------------------------------------
This seems to work fine in my testing - thanks!
I did wonder whether we could -always- use the "force root update" approach, and then dispense with the code that watches for backing scale factor changes on nsCocoaWindow, as it would be triggered by the child view. Might make things a bit simpler overall - WDYT?
::: layout/base/nsPresContext.cpp
@@ +1677,5 @@
> +{
> + mPendingUIResolutionChanged = false;
> +
> + mDeviceContext->CheckDPIChange();
> + if (uint32_t(mCurAppUnitsPerDevPixel) != AppUnitsPerDevPixel()) {
You can drop the typecast here since bug 842514 landed. :)
Attachment #716848 -
Flags: feedback?(jfkthame) → feedback+
Assignee | ||
Comment 5•12 years ago
|
||
(In reply to Jonathan Kew (:jfkthame) from comment #4)
> I did wonder whether we could -always- use the "force root update" approach,
> and then dispense with the code that watches for backing scale factor
> changes on nsCocoaWindow, as it would be triggered by the child view. Might
> make things a bit simpler overall - WDYT?
Forget I said that, I don't think it's useful (it won't reach up into the chrome).
Comment 6•12 years ago
|
||
>> I did wonder whether we could -always- use the "force root update"
>> approach, and then dispense with the code that watches for backing
>> scale factor changes on nsCocoaWindow, as it would be triggered by
>> the child view. Might make things a bit simpler overall - WDYT?
>
> Forget I said that, I don't think it's useful (it won't reach up
> into the chrome).
It's also inefficient. aForceRootUpdate actually forces a call to
AppUnitsPerDevPixelChanged() in the root presentation shell, whether
or not rootPC->mCurAppUnitsPerDevPixel ==
rootPC->AppUnitsPerDevPixel(). And there can be more than one
nsChildView per nsCocoaWindow (if the page includes one or more
plugins).
This forcing was deliberate, and was necessary to deal with the
following problem:
At first I just found the root shell and called
BackingScaleFactorChanged() on it from
nsDocShell::RestoreFromHistory(). And this actually worked in last
week's trunk code. But when I refreshed my clone early this week, I
found that it no longer worked (that some recent change had broken
it).
In retrospect, it actually *shouldn't* have worked. The native
window's backing scale factor will normally already have been changed
to the correct value by the time nsDocShell::RestoreFromHistory() is
called (this should have happened when the user moved the window from
one monitor to the other). Which means
rootPC->AppUnitsPerDevPixelChanged() won't get called again unless we
somehow force it.
I don't fully understand why the second call to
rootPC->AppUnitsPerDevPixelChanged() is needed. But my tests show
that it is.
Comment 7•12 years ago
|
||
Carrying forward Jonathan's feedback+
Attachment #716848 -
Attachment is obsolete: true
Attachment #717176 -
Flags: review?(roc)
Attachment #717176 -
Flags: feedback+
Assignee | ||
Comment 8•12 years ago
|
||
Once we have a reviewed-and-landed patch here, we should uplift it to aurora-21 and beta-20 if at all possible, so that it goes out with the rest of hidpi/multiscreen support.
This doesn't seem right to me. I expect to see code added that just updates the device context for the document that was retrieved from the bfcache, and its descendant documents. I don't know why we have to go back to the root.
Comment 10•12 years ago
|
||
It's quite clear that we *do* have to go back to root, and that we have to call rootPC->AppUnitsPerDevPixelChanged() a "second" time ... or some part of that method. But I don't fully understand why, either. Do you have any ideas?
Comment 11•12 years ago
|
||
> It's quite clear that we *do* have to go back to root ...
At least on OS X, which is so far the only place I've tested.
Do we have working HiDPI support on Windows or Linux, and is there a practical way to test it?
(In reply to Steven Michaud from comment #11)
> Do we have working HiDPI support on Windows or Linux, and is there a
> practical way to test it?
Not for dynamic changes, no.
(In reply to Steven Michaud from comment #10)
> It's quite clear that we *do* have to go back to root, and that we have to
> call rootPC->AppUnitsPerDevPixelChanged() a "second" time ... or some part
> of that method. But I don't fully understand why, either. Do you have any
> ideas?
No, I'm afraid not.
Assignee | ||
Comment 13•12 years ago
|
||
Here's my latest attempt to fix this - seems to work in initial testing, at least.
Assignee | ||
Updated•12 years ago
|
Assignee: smichaud → jfkthame
Assignee | ||
Updated•12 years ago
|
Attachment #725115 -
Flags: review?(roc)
Attachment #725115 -
Flags: feedback?(smichaud)
Comment 14•12 years ago
|
||
Comment on attachment 725115 [details] [diff] [review]
handle possible resolution change when restoring content from history
Looks fine to me. It seems to be functionally equivalent to my patch, while being a lot simpler.
Attachment #725115 -
Flags: feedback?(smichaud) → feedback+
Comment on attachment 725115 [details] [diff] [review]
handle possible resolution change when restoring content from history
Review of attachment 725115 [details] [diff] [review]:
-----------------------------------------------------------------
::: layout/base/nsPresContext.cpp
@@ +1680,5 @@
> if (mCurAppUnitsPerDevPixel != AppUnitsPerDevPixel()) {
> AppUnitsPerDevPixelChanged();
> + nsPresContext* rootPC = GetRootPresContext();
> + if (rootPC && rootPC != this && rootPC->mShell) {
> + rootPC->mShell->ReconstructFrames();
I still don't understand why we have to reconstruct frames for the entire browser window.
Assignee | ||
Comment 16•12 years ago
|
||
If we don't, the content that was restored from history into the window is scaled correctly, but its view fills only the top-left quarter of the window (if the move was from hidpi to lodpi) or extends to double the window's width and height (if vice-versa).
Presumably that's because it uses its "old" dpi to size itself when it is being inserted into the window, or something like that.
Calling ReconstructFrames on the root shell fixes that. Maybe there'd be a lighter-weight way to fix it, but so far I haven't found it. We're open to suggestions of where to poke at it...
(In reply to Jonathan Kew (:jfkthame) from comment #16)
> Presumably that's because it uses its "old" dpi to size itself when it is
> being inserted into the window, or something like that.
>
> Calling ReconstructFrames on the root shell fixes that. Maybe there'd be a
> lighter-weight way to fix it, but so far I haven't found it. We're open to
> suggestions of where to poke at it...
I'd like to actually understand what the bug is before we work around it.
I'm pretty sure you should call BackingScaleFactorChanged() before Thaw(), for one thing. In fact I think basically we should call BackingScaleFactorChanged() as early as possible during the restoration process, as soon as we've obtained the shell. I'm suspicious of the oldBounds/newBounds stuff being wrong.
Assignee | ||
Comment 18•12 years ago
|
||
I've already experimented with moving the BackingScaleFactorChanged() call earlier in RestoreFromHistory() (immediately after we get the shell), but it didn't help any.
OK, but it's really important we understand what this bug is and fix it properly instead of working around it.
Assignee | ||
Comment 20•12 years ago
|
||
The reason simply calling shell->BackingScaleFactorChanged() wasn't sufficient is that nsPresContext uses a runnable to actually implement the update, so this call does not cause the device context's appUnitsPerDevPixel to be immediately updated - it will happen later on the event loop. But this means that it is still out-of-date at the point where we call mContentViewer->SetBounds to adjust the size of the restored viewer, and hence we get it wrong. This version of the patch fixes this by explicitly calling CheckDPIChange on the dev context, so that its appPerDev value will be correct by the time we rely on it for sizing the widget. (An alternative solution would be to make nsPresContext::UIResolutionChanged() work synchronously, instead of via a runnable; I've confirmed that would also fix the problem, but it's probably less desirable overall.)
Attachment #736769 -
Flags: review?(roc)
Assignee | ||
Updated•12 years ago
|
Attachment #736769 -
Flags: feedback?(smichaud)
Comment 21•12 years ago
|
||
Comment on attachment 736769 [details] [diff] [review]
check for possible DPI change when restoring content from browser history
Looks good to me. Nice catch!
Attachment #736769 -
Flags: feedback?(smichaud) → feedback+
Comment on attachment 736769 [details] [diff] [review]
check for possible DPI change when restoring content from browser history
Review of attachment 736769 [details] [diff] [review]:
-----------------------------------------------------------------
Great, thanks!
Attachment #736769 -
Flags: review?(roc) → review+
Assignee | ||
Comment 23•12 years ago
|
||
Target Milestone: --- → mozilla23
Assignee | ||
Updated•12 years ago
|
Attachment #717176 -
Attachment is obsolete: true
Attachment #717176 -
Flags: review?(roc)
Assignee | ||
Updated•12 years ago
|
Attachment #725115 -
Attachment is obsolete: true
Attachment #725115 -
Flags: review?(roc)
Comment 24•12 years ago
|
||
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 25•12 years ago
|
||
While this is a relatively obscure issue - it only occurs when a user moves the browser window between Retina and non-Retina screens, and then moves backward or forward through cached pages - the result is pretty ugly.
Given how simple and safe the fix is, I think we should uplift this to fix the regression for Retina-plus-external-display users.
Assignee | ||
Comment 26•12 years ago
|
||
Comment on attachment 736769 [details] [diff] [review]
check for possible DPI change when restoring content from browser history
[Approval Request Comment]
Bug caused by (feature/regressing bug #): HiDPI (Retina) display and OS X multiple screen support
User impact if declined: bad display (double- or half-size web content) after moving window between screens and then clicking Back or Forward to go to a page from the bfcache.
Testing completed (on m-c, etc.): several days on Nightly
Risk to taking this patch (and alternatives if risky): minimal risk - localized patch that has no effect unless there's a DPI mismatch, and in that case just calls existing resolution-update code
String or IDL/UUID changes made by this patch: none
Attachment #736769 -
Flags: approval-mozilla-beta?
Attachment #736769 -
Flags: approval-mozilla-aurora?
Updated•12 years ago
|
status-firefox21:
--- → affected
status-firefox22:
--- → affected
Comment 27•12 years ago
|
||
Comment on attachment 736769 [details] [diff] [review]
check for possible DPI change when restoring content from browser history
The patch looks contained and safe and it helps avoid bad display issues for users using mixed low/high-DPI screens .Will back-out if we see any new regressions off this.
:jfkthame, I am going to request some exploratory testing around this from QA, but any local testing you can further do to be more confident will be very helpful in case you have the set-up ready.
Attachment #736769 -
Flags: approval-mozilla-beta?
Attachment #736769 -
Flags: approval-mozilla-beta+
Attachment #736769 -
Flags: approval-mozilla-aurora?
Attachment #736769 -
Flags: approval-mozilla-aurora+
Comment 28•12 years ago
|
||
(In reply to chrille_b from comment #0)
> User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0)
> Gecko/20130114 Firefox/20.0
> Build ID: 20130114042016
>
> Steps to reproduce:
>
> Use mixed lo/hi-dpi screens with a macbook retina.
> Open firefox on a hi-dpi screen.
> Open a website (e.g. www.google.com) and search for something or click on a
> link.
> Move firefox window to a lo-dpi screen.
> Click on the back button.
>
>
> Actual results:
>
> The window has the wrong devicePixelRatio. It has the value of 2 (which was
> the value of my hi-dpi screen when the page was loaded at that screen).
>
> This happens on firefox 20+ (Aurora and Nightly).
>
> Expected results:
>
> devicePixelRatio should have a value of 1.
Hi chrille_b,
Can you please try our latest nightly to see if the issue is fixed for you ?
Thanks for reporting the issue and hope this is resolved for you now.
Assignee | ||
Comment 29•12 years ago
|
||
Assignee | ||
Comment 30•12 years ago
|
||
(In reply to bhavana bajaj [:bajaj] from comment #27)
> :jfkthame, I am going to request some exploratory testing around this from
> QA, but any local testing you can further do to be more confident will be
> very helpful in case you have the set-up ready.
The key elements needed to reproduce the bug are (a) Mac with a mix of Retina and non-Retina screens; (b) navigating backwards and forwards among cached pages in the bfcache; and (c) interspersed with that, moving the browser window between screens with differing resolution. In this way, I was consistently able to trigger the incorrect display for content reloaded from the cache.
Once the patch was applied, I have been unable to reproduce it in repeated testing. So for my configuration, at least, I'm pretty confident the issue is resolved. Additional QA testing is of course welcome.
Comment 31•12 years ago
|
||
Matt, can you please verify this is fixed? It should currently be fixed in Firefox Nightly 23.0a1 builds and should be fixed in tomorrow's Aurora and the next Beta.
QA Contact: mwobensmith
Reporter | ||
Comment 32•12 years ago
|
||
(In reply to bhavana bajaj [:bajaj] from comment #28)
> (In reply to chrille_b from comment #0)
> > User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0)
> > Gecko/20130114 Firefox/20.0
> > Build ID: 20130114042016
> >
> > Steps to reproduce:
> >
> > Use mixed lo/hi-dpi screens with a macbook retina.
> > Open firefox on a hi-dpi screen.
> > Open a website (e.g. www.google.com) and search for something or click on a
> > link.
> > Move firefox window to a lo-dpi screen.
> > Click on the back button.
> >
> >
> > Actual results:
> >
> > The window has the wrong devicePixelRatio. It has the value of 2 (which was
> > the value of my hi-dpi screen when the page was loaded at that screen).
> >
> > This happens on firefox 20+ (Aurora and Nightly).
> >
> > Expected results:
> >
> > devicePixelRatio should have a value of 1.
>
> Hi chrille_b,
>
> Can you please try our latest nightly to see if the issue is fixed for you ?
>
> Thanks for reporting the issue and hope this is resolved for you now.
Hi,
yes, I can confirm that the issue is fixed for me in the latest nightly build 23.0a1 (2013-04-20) and the latest aurora build 22.0a2 (2013-04-20).
Thank you all for resolving the issue.
Comment 33•12 years ago
|
||
Thank you chrille_b. We should have a new beta build with this fix by mid-week.
Status: RESOLVED → VERIFIED
Comment 34•12 years ago
|
||
Confirmed broken 2013-02-05, builds 20 and up.
Confirmed fixed 2013-04-22, 22.0a2 and 23.0a1.
Comment 35•12 years ago
|
||
(In reply to Matt Wobensmith from comment #34)
> Confirmed broken 2013-02-05, builds 20 and up.
> Confirmed fixed 2013-04-22, 22.0a2 and 23.0a1.
Thanks Matt. We now have Firefox 21.0b4 candidate builds. Can you please verify this is fixed in Beta?
ftp://ftp.mozilla.org/pub/firefox/nightly/21.0b4-candidates/build1/
Comment 36•12 years ago
|
||
Thanks Anthony.
Confirmed fixed 21.0b4.
You need to log in
before you can comment on or make changes to this bug.
Description
•