Skip to content

Fix pinch-to-zoom remaining active when page zoom is set#6896

Open
zry98 wants to merge 2 commits into
home-assistant:mainfrom
zry98:fix/page-zoom-pinch
Open

Fix pinch-to-zoom remaining active when page zoom is set#6896
zry98 wants to merge 2 commits into
home-assistant:mainfrom
zry98:fix/page-zoom-pinch

Conversation

@zry98
Copy link
Copy Markdown
Contributor

@zry98 zry98 commented May 25, 2026

Summary

When "Page zoom" is set to anything other than the default 100%, the webview still accepts pinch gestures to zoom with a small range around the configured initial scale, even when "Pinch-to-zoom" is disabled.

The root cause is toggling WebSettings.builtInZoomControls alone is not enough to disable pinch when a custom setInitialScale is applied, this fix toggles WebSettings.setSupportZoom together so that disabling pinch-to-zoom fully disables it regardless of the configured page zoom.

After this fix, I noticed that toggling pinch-to-zoom only took effect after changing the page zoom. I found it's because in LocalStorageImpl.observeChanges, awaitClose was placed inside the keys.forEach loop, the coroutine suspended after the first iteration, so the listeners for the remaining keys were never registered. The first key was effectively the only one observed, changes to later keys are ignored silently.

I have opened another PR for that fix: #6902

Checklist

  • New or updated tests have been added to cover the changes following the testing guidelines.
  • The code follows the project's code style and best_practices.
  • The changes have been thoroughly tested, and edge cases have been considered.
  • Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Any other notes

Depends on #6902 to be merged to work properly.

@jpelgrom
Copy link
Copy Markdown
Member

Thanks for the fix! Do you have a good way to reproduce the issue so we can validate it?

I found it's because in LocalStorageImpl.observeChanges, awaitClose was placed inside the keys.forEach loop, the coroutine suspended after the first iteration, so the listeners for the remaining keys were never registered. The first key was effectively the only one observed, changes to later keys are ignored silently.

So the second fix is replacing the per-key listeners with a single listener that filters by the watched key set and registers/unregisters once.

Could you submit this separately? It may be required for this PR but we can review it standalone.

@zry98
Copy link
Copy Markdown
Contributor Author

zry98 commented May 25, 2026

Do you have a good way to reproduce the issue so we can validate it?

@jpelgrom I couldn't reproduce it until I reinstalled the app (clearing data didn't work), not sure why is that. Below is the screen recording reproducing this bug:

out.mp4

Could you submit this separately?

Sure, I've moved it to another PR: #6902

@@ -136,7 +144,10 @@ sealed interface WebViewAction {
override fun run(webView: WebView) {
Copy link
Copy Markdown
Member

@TimoPtr TimoPtr May 26, 2026

Choose a reason for hiding this comment

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

That's my fault but we misses some unit tests on the WebViewActions can you at least add the one for the ApplyZoom action? It should verify that we call the right settings with the right value and help us avoid making unwanted mistake in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@TimoPtr thanks for your work! Sure, I've added two tests

@zry98 zry98 force-pushed the fix/page-zoom-pinch branch from 0a975b9 to 439ca3e Compare May 30, 2026 02:12

verify { webView.settings.setSupportZoom(true) }
verify { webView.settings.builtInZoomControls = true }
assertTrue(scriptSlot.captured.contains("user-scalable=yes"))
Copy link
Copy Markdown
Member

@jpelgrom jpelgrom May 30, 2026

Choose a reason for hiding this comment

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

This isn't a good test, because the script will always contain user-scalable=yes and only once it's evaluated will it actually run the script and decide which branch to use. You can copy this line and add it to the test with pinchToZoomEnabled false, copy the scriptSlot line from that test to this one, and both tests will still pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants