Open Bug 1024493 Opened 11 years ago Updated 3 years ago

How to accurately get the available screen size (inner and outer) in fractional CSS pixels?

Categories

(Core :: DOM: Core & HTML, defect, P5)

ARM
Gonk (Firefox OS)
defect

Tracking

()

REOPENED

People

(Reporter: jujjyl, Unassigned)

Details

Testing on the FFOS Flame device that has a screen resolution of 480x854 device pixels and a window.devicePixelRatio of 1.5: 1. Connect the FFOS device via USB, make sure ADB and DevTools debugging options are enabled. Make sure the screen is powered on and the lock screen is not active. 2. Run the following commands on the command line: wget https://raw.githubusercontent.com/kripken/emscripten/incoming/tools/ffdb.py chmod +x ffdb.py wget http://clb.demon.fi/bugs/dip.zip ./ffdb.py install dip.zip --run --log 3. Acknowledge the incoming debug connection on the device 4. Observe the log print Observed: the log reads dip.html:10: window.devicePixelRatio: 1.5 dip.html:11: screen.width/height: 320x569 dip.html:12: screen.availWidth/height: 320x569 dip.html:13: window.innerWidth/height: 320x569 dip.html:14: window.outerWidth/height: 320x569 dip.html:15: document.body.clientWidth/height: 320x569 dip.html:16: document.body.offsetWidth/height: 320x569 dip.html:17: document.body.scrollWidth/height: 320x569 dip.html:18: document.documentElement.clientWidth/height: 320x569 dip.html:19: document.documentElement.offsetWidth/height: 320x569 dip.html:20: document.documentElement.scrollWidth/height: 320x569 dip.html:21: document.documentElement.getBoundingClientRect().width/height: 320x569.3333129882812 Expected: For all printed items, the log should read height as 569.3333129882812 instead of having truncated down to integer value 569. Only the last reported item document.documentElement.getBoundingClientRect().height prints the screen size properly.
> For all printed items, the log should read height as 569.3333129882812 instead of having > truncated down to integer value 569. Per spec, all of those are defined to be integers, not floats, so the observed behavior is unfortunately correct... You want to be using non-broken APIs like getBoundingClientRect/getClientRects/getBoxQuads to get geometry information, not offset*/client*.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → INVALID
Oh, that is extremely unfortunate, and in my view, makes the spec broken. Let me reopen this to propose the following question then: Is .getBoundingClientRect() the only api that we can use to query fractional CSS pixel sizes? If I want to get the accurate fractional CSS pixel size of the screen, with that function I must first carefully construct a web page that *exactly* has the following content, and that only: <body style="margin:0px; width: 100%; height: 100%;"> <canvas style="width: 100%; height: 100%;"></canvas> </body> since otherwise the content of the page is not "large enough" that document.documentElement.getBoundingClientRect() would return the size of the whole display, and if I put other content there so that the screen would scroll, it reports too large sizes. This makes it an extremely difficult api to use, since I would have to effectively destroy all contents on the page first, and then add that test content, use .getBoundingClientRect(), then remove the test contents and replace with the real page contents.
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
Summary: screen.(avail)height, window.inner/outer/Height, document.body.client/offset/scrollHeight and document.documentElement.client/offset/scrollHeight all report wrong values on the Flame. → How to accurately get the available screen size (inner and outer) in fractional CSS pixels?
> Is .getBoundingClientRect() the only api that we can use to query fractional CSS pixel > sizes? No, see comment 1. But all those APIs are for elements. > If I want to get the accurate fractional CSS pixel size of the screen roc, how do you feel about adding new accessors on Screen for this use case?
Flags: needinfo?(roc)
That said, are you really interested in _screen_ size? Or are you interested in _viewport_ size?
Right, what I meant is to have APIs that could be used without having to create DOM content first for querying purposes, and after that replace with the proper content, i.e. without having to mutate the DOM to do that. Could we work towards changing the spec? That would be the cleanest solution? Is there a specific reason that using ints was chosen (I cannot imagine one), or is that just due to historical oversight? I am interested in both the screen size and the viewport sizes. In some applications, people will typically set fullscreen: true; in the app manifest for the FFOS packaged app to make those effectively the same, but in others, I imagine that people will want to leave those as is, and keep the FFOS title bar there, and get just the viewport area.
> Could we work towards changing the spec? Maybe. > Is there a specific reason that using ints was chosen The spec was written to reflect longstanding browser behavior (because none of those things you mention above except getBoundingClientRect _started_ with standards) and browsers used to always return integers because they only did integer layout... Changing the return values is likely to cause site breakage; adding new APIs that return doubles is doable.
Ok, that's understandable. In case of a new API, I would propose having something like screen.widthF & .heightF screen.availWidthF & .availHeightF window.innerWidthF & .innerHeightF window.outerWidthF & .outerHeightF and so on. The names can be adjusted if people would find that too ugly, but having a straightforwardly mirrored versions of the integer properties as float properties would be cleanest.
document.getBoxQuads().bounds.width/height returns the viewport width and height with subpixel precision. Do authors really need subpixel precision for window.outer* and screen.*? I don't yet see that they do. It seems from the comments in this bug what's really needed is the viewport size.
Flags: needinfo?(roc)
I don't really want to join the webgl mailing list just to respond to the thread there. I think this should be re-raised on WHATWG, it's not really a WebGL issue. document.getBoxQuads().bounds.width/height, and multiplying by devicePixelRatio, should give good results when the canvas is filling the viewport and you're the toplevel document and zooming is disabled. Other situations are a bit more difficult to handle. When the canvas isn't filling the viewport, there could be various kinds of snapping being performed by the browser that could cause off-by-one errors no matter what method you use. Maybe we should expose on the canvas element attributes "renderedPixelWidth" and "renderedPixelHeight" which contain the values you should set for "width" and "height" to get the best device-pixel-accurate rendering.
Well, either we fix screen.* and window.outer* so that they will work on devices with fractional windows.devicePixelRatio, or we should call them broken and advocate users to never to rely on them and document that they are broken and don't return the correct size. A lot of mobile HTML5 WebGL development pages that talk about sizing canvases currently mention using screen.*, so it's sad to see the web fill with broken examples. I don't know about the window.outer*, perhaps that one is not so common, but I don't see why we couldn't to the proper thing while we are at it. Getting the proper viewport size is most important. I will have to test how document.getBoxQuads() behaves. If that is documented to work without having to mutate the html page, then I guess that is a good solution and the replacement that should be advocated for screen.* et al. Is that a standard that other browsers support as well? The renderedPixelWidth/Height properties sound nice, I would be happy with those.
(In reply to Jukka Jylänki from comment #11) > Well, either we fix screen.* and window.outer* so that they will work on > devices with fractional windows.devicePixelRatio, or we should call them > broken and advocate users to never to rely on them and document that they > are broken and don't return the correct size. A lot of mobile HTML5 WebGL > development pages that talk about sizing canvases currently mention using > screen.*, so it's sad to see the web fill with broken examples. Assuming that your viewport fills the screen is totally broken no matter what. It means your app doesn't work non-fullscreen in a desktop browser, or any mobile platform (current or future) supporting more than one visible app at a time. > I don't know > about the window.outer*, perhaps that one is not so common, but I don't see > why we couldn't to the proper thing while we are at it. Getting the proper > viewport size is most important. Almost every use of window.outer* is totally broken. What difference should it make to an app how thick the window borders are, if any? Anytime someone uses window.outer* to size something on mobile I bet they're assuming there are no window borders. > I will have to test how document.getBoxQuads() behaves. If that is > documented to work without having to mutate the html page, then I guess that > is a good solution and the replacement that should be advocated for screen.* > et al. Is that a standard that other browsers support as well? No other browser supports it yet, but there is a spec with consensus: http://dev.w3.org/csswg/cssom-view/#the-geometryutils-interface Chrome will catch up. > The renderedPixelWidth/Height properties sound nice, I would be happy with > those. I'll suggest it on WHATWG then.
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #12) > (In reply to Jukka Jylänki from comment #11)> > > The renderedPixelWidth/Height properties sound nice, I would be happy with > > those. > > I'll suggest it on WHATWG then. +1
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046 Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5. If you have questions, please contact :mdaly.
Priority: -- → P5
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.