Skip to content

Conversation

ayushman1210
Copy link

Resolves #8121

Changes:

  • Modified the getWindowWidth() and getWindowHeight() functions in environment.js to prioritize document.documentElement.clientWidth and document.documentElement.clientHeight over window.innerWidth and window.innerHeight.
  • This resolves an issue in Chrome on Android where windowWidth and windowHeight values do not update correctly when the device is rotated between portrait and landscape orientation.
  • Updated logic ensures consistent behavior across mobile browsers while maintaining backward compatibility with desktop browsers.

PR Checklist

  • npm run lint passes
  • Inline reference is included / updated
  • Unit tests are included / updated

Copy link

welcome bot commented Oct 3, 2025

🎉 Thanks for opening this pull request! For guidance on contributing, check out our contributor guidelines and other resources for contributors!
🤔 Please ensure that your PR links to an issue, which has been approved for work by a maintainer; otherwise, there might already be someone working on it, or still ongoing discussion about implementation. You are welcome to join the discussion in an Issue if you're not sure!
🌸 Once your PR is merged, be sure to add yourself to the list of contributors on the readme page !

Thank You!

@eyaler
Copy link

eyaler commented Oct 3, 2025

@ayushman1210 Thanks! I think innerWidth should be before body.clientWidth as the body dimensions reflect the content and not the viewport. Also, the suggested change may have issue when scrollbars are present (in Chrome they are part of the innerWidth but not of the documentElement.clientWidth) - I did not look into this yet.

@ayushman1210
Copy link
Author

Hi @eyaler ,

Thanks for the feedback! I’ve updated the code so that window.innerWidth and window.innerHeight are checked first, before document.body.clientWidth and document.documentElement.clientWidth/Height. This ensures the viewport dimensions are captured correctly and also handles scrollbars properly in Chrome.

Thanks
Ayushman

Copy link
Collaborator

@perminder-17 perminder-17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what's the reason behind removing all the docs? I think you need to fix the PR with the minimal changes whatever needed.

@eyaler
Copy link

eyaler commented Oct 4, 2025

@ayushman1210 i don't get it. this was the state of things before with the issue that innerWidth may be wrong, no? my suggestion was that document.documentElement.clientWidth will be used first (but i think we need more feedback before making this change)

@ayushman1210
Copy link
Author

@eyaler
good catch and thanks for the feedback.
Quick recap of what I changed so far

  • I fixed the timing issue by deferring the resize handler to the next animation frame so layout has settled after rotation (so windowResized() sees the post-rotation viewport).

  • I also updated getWindowWidth() / getWindowHeight() to prefer visualViewport (when available) and then fall back to other viewport measures

About your suggestion (use [document.documentElement.clientWidth] first )

  • I agree that preferring [document.documentElement.clientWidth] avoids surprising inclusion of scrollbar width in many desktop Chrome cases — that was exactly your point.

The tradeoffs:

  • [documentElement.clientWidth] tends to reflect the CSS/layout viewport and avoids scrollbars, which is often what sketches expect.

  • [window.innerWidth] includes scrollbars on some browsers; that can make sketch sizing look different when scrollbars appear.

  • [window.visualViewport] (when available) is still the best for mobile cases (on-screen keyboard, pinch-zoom) so I kept it as the top preference.

Because timing of which value updates when can vary across browsers, I left the resize handler deferred to rAF so whichever source we pick will be read after layout has updated.

Proposed conservative change (what I can implement now)

Use the following order in [getWindowWidth()] / [getWindowHeight()] :
[window.visualViewport (when available)
[document.documentElement.clientWidth]/ [clientHeight]
[window.innerWidth] / [innerHeight]
[document.body.clientWidth]/ [clientHeight]
This matches your suggestion while preserving [visualViewport] for mobile edge cases.

Questions / next steps

Is that ordering acceptable to you (visualViewport -> documentElement -> innerWidth -> body)?
If yes I’ll update the PR to use this ordering and push the change.
If you prefer a different rule (e.g., a heuristic that switches based on scrollbar presence, or exposing a small opt-in API to choose the preference), tell me and I’ll implement that instead.

Thanks
Ayushman

@eyaler
Copy link

eyaler commented Oct 4, 2025

thanks @ayushman1210

* I fixed the timing issue by deferring the resize handler to the next animation frame so layout has settled after rotation (so windowResized() sees the post-rotation viewport).

I coundn't find the added requestAnimationFrame in your PR, and in my own testing requestAnimationFrame did not solve the issue. Can you point me to the commit/line?

* I also updated getWindowWidth() / getWindowHeight() to prefer visualViewport (when available) and then fall back to other viewport measures

In my testing visualViewport does not include scrollbars just as documentElement.clientWidth, and also is wrong when rotating back just as innerWidth. I did find viewport.segments[0].width that seems to both include scrollbars and be correct after orientation change but that is still experimental and has partial support (and i don't have a good enough understanding of it)

* I agree that preferring [document.documentElement.clientWidth] avoids surprising inclusion of scrollbar width in many desktop Chrome cases — that was exactly your point.

On the contrary, I actully think scrollbar should be included if possible

…able

Prefer experimental visualViewport.segments[0] and visualViewport before window.inner* so measurements include scrollbars and handle orientation changes when available. Guard experimental access and fall back to documentElement.client* for compatibility.
@ayushman1210
Copy link
Author

@eyaler Hi maintainer !!
I pushed a change on branch fix/chrome-window-innerwidth (commit 4b5ee8b) that adjusts how p5 computes viewport size in [environment.js]: it now prefers [visualViewport.segments[0]] (when available), then [window.visualViewport] then [window.inner*] (so scrollbars are included when possible), and finally falls back to [document.documentElement.client*]and [document.body.client*]). Experimental accesses are guarded with try/catch.
I ran the full test suite locally (all tests passed). Please let me know if you'd prefer excluding the experimental [segments] usage or a different fallback order — I can update quickly.

Thanks
ayushman

@eyaler
Copy link

eyaler commented Oct 5, 2025

@ayushman1210 sorry but i am not a maintainer... btw, i still couldn't find where you used requestAnimationFrame

@ayushman1210
Copy link
Author

@eyaler
You're absolutely right about the scrollbar issue. I've removed visualViewport.width from the fallback chain to avoid the inconsistency.

Updated implementation:

  • Priority 1: visualViewport.segments[0] (experimental foldable/dual-screen API)
  • Priority 2: window.innerWidth (includes scrollbars, matches historical p5.js behavior)
  • Priority 3: document.documentElement.clientWidth (fallback when innerWidth unavailable)
  • Priority 4: document.body.clientWidth (last resort)

The segments API is only used when explicitly available (for foldable devices), then we fall back directly to innerWidth. This avoids the Chrome scrollbar issue you mentioned while still supporting dual-screen devices.

Regarding requestAnimationFrame: I apologize for any confusion - I did NOT add or modify any RAF code. My changes are limited to the getWindowWidth() and getWindowHeight() helper functions, which are only called:

  1. On initialization in _updateWindowSize()
  2. In the _onresize event handler

These functions are NOT called in the animation loop, so there's no per-frame performance impact.

Thanks
Ayushman

@ayushman1210
Copy link
Author

Hi @perminder-17
can you please Review this PR #8122 for the issue #8121

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rotating device to landscape and back gives wrong windowWidth after resizeCanvas
3 participants