NEW 170595
window.innerWidth/innerHeight are bogus after resize/orientationchange in WKWebView (but not MobileSafari)
https://bugs.webkit.org/show_bug.cgi?id=170595
Summary window.innerWidth/innerHeight are bogus after resize/orientationchange in WKW...
ae
Reported 2017-04-07 03:54:03 PDT
When my iPhone SE is rotated from portrait to landscape or vice versa, both resize and orientationchange events are generated on window (OK). However, in the respective event handlers, window.innerWidth/innerHeight have useless / bogus values. For example, in a resize handler, they'll BOTH (!) be 320 (last time I checked, my iPhone wasn't square), and in the orientationchange handler, it will still have the values from the PREVIOUS orientation. This is a major showstopper for hybrid apps that aim to support both orientations. Introduced in iOS 10.3.1. 10.2 was fine.
Attachments
test page (1.26 KB, text/html)
2017-04-21 12:00 PDT, Tim Horton
no flags
ae
Comment 1 2017-04-07 03:55:04 PDT
(this occurs in WKWebView)
Radar WebKit Bug Importer
Comment 2 2017-04-07 08:46:12 PDT
Ali G
Comment 3 2017-04-11 11:08:04 PDT
This also broke AMP's image viewer in 10.3: https://github.com/ampproject/amphtml/issues/8479 Prioritized commitment to fix this would be very much appreciated.
Sriram Krishnan
Comment 4 2017-04-11 11:13:03 PDT
This affects a large subset of AMP pages (likely a few 100 million). This will represent a significant regression in UX.
ae
Comment 5 2017-04-11 11:22:32 PDT
If anyone is interested and/or trying to find a workaround for their situation: Both events are completely useless right now, as they never get called with the correct values for innerWidth/Height in place. The quick fix I immediately deployed in my production apps was to just introduce a timeout in the orientationchange handler (0.7s), as I hoped that after 0.7 seconds, the values are finally correct (seems to be the case). The "real" fix was to constantly check both innerWidth and innerHeight (say, 10 times per second) and if any of them changes, generate a "fake" resize event. That works, but is of course a waste of CPU and battery.
Tim Horton
Comment 6 2017-04-21 11:56:15 PDT
Hello! Can you, by any chance, attach a test app that reproduces the regression? I can reproduce the problem, but I can *also* reliably reproduce it in earlier versions of iOS, so I'm not sure I'm testing the same thing as you.
Tim Horton
Comment 7 2017-04-21 12:00:48 PDT
Created attachment 307766 [details] test page
Tim Horton
Comment 8 2017-04-21 13:44:12 PDT
OK, the AMP problem is actually not a duplicate of this. Splitting that out into https://bugs.webkit.org/show_bug.cgi?id=171140.
ae
Comment 9 2017-04-22 08:27:17 PDT
(In reply to Tim Horton from comment #6) > Hello! Can you, by any chance, attach a test app that reproduces the > regression? I can reproduce the problem, but I can *also* reliably reproduce > it in earlier versions of iOS, so I'm not sure I'm testing the same thing as > you. Hello. I'm not completely sure really what changed and when, all I know is that the app's orientation change handling was broken the moment I updated to iOS 10.3.1. Here's some debug output from the handlers (window.orientation in parentheses) : --- After rotating the phone from portrait to landscape: --- ORIENTATIONCHANGE: 320 x 568 (90) RESIZE: 320 x 320 (90) App.resize (from update): 568 x 320 - wrong (old portrait) dimensions in orientationchange handler - wrong dimensions in resize handler (square!) - App.resize is the "fake" handler I wrote which manually detects size changes (fine) --- After rotating back to portrait: --- ORIENTATIONCHANGE: 568 x 320 (0) RESIZE: 320 x 320 (0) App.resize (from update): 320 x 568 - wrong (old landscape) dimensions in orientationchange handler - wrong dimensions again in resize handler Note that there's NEVER a correct 'resize' event generated with the correct values for innerWidth/innerHeight! Hope this helps. Probably a difficult one to get fixed.
dopıng
Comment 10 2017-04-23 06:06:44 PDT
No idea whether this is related, but just in case… There’s also been another change in the behavior of ‘window.innerHeight’ between iOS 10.2 and 10.3.1: When you touch an input field that’s located at the bottom of a page, the virtual keyboard comes up and Safari scrolls to ensure that the field remains visible. If you have a handler attached to the window’s ‘scroll’ event and read ‘window.innerHeight’ in it, in iOS 10.2 the height was unchanged, i.e. not reduced by the height of the keyboard. In iOS 10.3.1, it *is* reduced by the height of the keyboard.
Tim Horton
Comment 11 2017-04-24 12:59:38 PDT
(In reply to ae from comment #9) > > Hello. I'm not completely sure really what changed and when, Right, but I need to figure that out, so I can fix it! > all I know is that the app's orientation change handling was broken the moment I updated to iOS 10.3.1. > > Here's some debug output from the handlers (window.orientation in > parentheses) : Can you reduce the app to something you're willing to share? Either here, or at bugreport.apple.com if you would prefer? > Note that there's NEVER a correct 'resize' event generated with the correct > values for innerWidth/innerHeight! > > Hope this helps. Probably a difficult one to get fixed. If you can't reduce the app to something you can share, perhaps you could look at the test page that I attached and see what might be different between it and your app that causes this problem to not reproduce in the test page? I need to get to the point where I can reproduce the problem in order to diagnose.
Tim Horton
Comment 12 2017-04-24 13:06:04 PDT
(In reply to Tim Horton from comment #11) > (In reply to ae from comment #9) > > > > Hello. I'm not completely sure really what changed and when, > > Right, but I need to figure that out, so I can fix it! > > > all I know is that the app's orientation change handling was broken the moment I updated to iOS 10.3.1. > > > > Here's some debug output from the handlers (window.orientation in > > parentheses) : > > Can you reduce the app to something you're willing to share? Either here, or > at bugreport.apple.com if you would prefer? > > > Note that there's NEVER a correct 'resize' event generated with the correct > > values for innerWidth/innerHeight! > > > > Hope this helps. Probably a difficult one to get fixed. > > If you can't reduce the app to something you can share, perhaps you could > look at the test page that I attached and see what might be different > between it and your app that causes this problem to not reproduce in the > test page? > > I need to get to the point where I can reproduce the problem in order to > diagnose. Sorry, I forgot the context. Rather, I need to figure out why your app *didn't* reproduce in older versions of iOS, when the test page does.
Simon Fraser (smfr)
Comment 13 2017-05-08 13:22:21 PDT
We're sending a visible rect update with unobscuredContentRect (0,0) width=320 height=320) during rotation.
Simon Fraser (smfr)
Comment 14 2017-05-08 13:29:18 PDT
We end up with 320x320 by virtue of: unobscuredRectInContentCoordinates = CGRectIntersection(unobscuredRectInContentCoordinates, [self _contentBoundsExtendedForRubberbandingWithScale:scaleFactor]);
Simon Fraser (smfr)
Comment 15 2017-05-08 13:34:45 PDT
and that's because we haven't update the contentView bounds for rotation yet (this happens on a callback from the web process), so we're intersecting 320x568 with 548x320.
Simon Fraser (smfr)
Comment 16 2017-05-08 17:34:22 PDT
We can fix this by avoiding the intersection with the content view bounds (which is really just there to fix rubber banding), but the layout viewport rect is still wrong because it also relies on state from the web process (the documentRect). We really need to round-trip through the web process with the new size before we can reliably compute rects.
ae
Comment 17 2017-05-09 01:33:52 PDT
Sorry I couldn't provide a real testcase yet, just completely drowned in work. But as it seems, you've already found the problem. Thanks again for looking into this.
Ali G
Comment 18 2017-12-08 15:13:43 PST
Hi Webkit team, Given Simon has found the root cause and has a proposed fix here, is this something we can expect to see fixed soon? Current workaround with introducing 500ms+ delays really hurts users' expectations of great UX. Thank you
Cathy Z
Comment 19 2017-12-11 17:54:52 PST
Not
Cathy Z
Comment 20 2017-12-11 17:58:26 PST
Sorry, meant to find a way to subscribe / +1 to this bug, but accidentally saved a comment.
Matthew Henry
Comment 21 2018-01-30 03:49:57 PST
(In reply to Ali G from comment #18) > Hi Webkit team, > > Given Simon has found the root cause and has a proposed fix here, is this > something we can expect to see fixed soon? > > Current workaround with introducing 500ms+ delays really hurts users' > expectations of great UX. > > Thank you Ali, I'm not sure whether this will be relevant to you given that it's been a month or so since your comment, but I've had success with a zero-delay workaround by calling getBoundingClientRect() on an element that's been styled to fill 100% of the window size within the window's resize handler.
Ilya G.
Comment 22 2018-06-04 07:27:22 PDT
Is this bug actually fixed in iOS 11.4?
Maxim Ambrosevich
Comment 23 2018-06-05 03:51:48 PDT
Unfortunately, yes. Test on PWA app.
Ozmor
Comment 24 2018-08-31 01:01:03 PDT
I'm still have the same problem, I need to put time out to make it work. Does anyone have any other solutions ?
Mo Lam
Comment 25 2018-12-18 22:50:43 PST
A slightly different workaround: To avoid creating a new element, The following workaround seems to work fairly well for me: For non-Safari, get the layout viewport size from document.documentElement.clientHeight (& Width). Unfortunately, Safari's documentElement size does not update when the URL bar hides so I couldn't just apply it to all Webkit browser, but this bug just doesn't happen to Safari.
dennis.subachev1
Comment 27 2019-11-12 11:57:03 PST
Can confirm I still see this issue. I threw the test page up on stackblitz for anyone who wants to try themselves: https://typescript-pmaukj.stackblitz.io Going portrait -> landscape -> portrait will cut off a space at the bottom of the screen the size of the menu (footer?) bar. `window.innerHeight` will _not_ include the cut off region so there is nothing that can be done to fill it until the user scrolls. This is especially a problem in our web app because we have `overflow-y: scroll` type containers that have a min and max height of `window.innerHeight`.
ztforster
Comment 28 2020-06-05 18:52:28 PDT
I am seeing the same issue in iOS 13.3.1, also in a WKWebView. I was able to work around it by implementing the solution "constantly check both innerWidth and innerHeight (say, 10 times per second)". I feel very strongly about this, as I don't rightly understand why you'd even bother implementing the resize event if window dimensions aren't going to be accurate. The way it is now, you need this hack to implement any kind of SVG visualization that needs a different aspect ratio in landscape.
Simon Fraser (smfr)
Comment 29 2023-08-21 20:09:39 PDT Comment hidden (obsolete)
Simon Fraser (smfr)
Comment 30 2023-08-21 20:10:08 PDT Comment hidden (obsolete)
Dmytro Semenov
Comment 31 2025-03-21 22:58:10 PDT
FYI this still happens, mostly in webviews (for example, in Chrome on iOS). The example on stackblitz above shows the issue well. Just listening for the `resize` event should be sufficient.
Note You need to log in before you can comment on or make changes to this bug.