Skip to content

v4.2.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 01:44
· 13 commits to main since this release

✨ Features and improvements

  • Android: two-finger pinch-zoom, rotate and tilt — the two-finger gesture handling was reworked, porting maplibre-gl-js's two_fingers_touch model (MapLibreMapController.Android.cs). Each of zoom / rotate / tilt now activates independently off its own threshold (zoom: cumulative log2-zoom delta; rotate: pixels along the touch-circle circumference, scaled by the smallest finger separation seen; tilt: both fingers moving vertically in the same direction), so an ordinary pinch no longer also spins or tilts the map. The map also claims the touch stream from any ancestor ScrollView/ViewPager2 via requestDisallowInterceptTouchEvent, so gestures work when the map is hosted inside a scrolling/paged container.
  • Sample app: map pages are one continuous scroll — the demo map pages previously split the screen into a map area and a separate fixed control panel (two disconnected surfaces). Each map page is now a single ScrollView with the map at the top (bounded height) and the controls flowing directly beneath, so dragging the map pans it while dragging the controls scrolls the page.

🐞 Bug fixes

  • Android: app crashed (native stack overflow) as soon as the map opened — the render callback ran Render() + RunLoop.RunOnce() synchronously from inside mbgl's update() dispatch, so a burst of tile-load events during the initial style load recursed on the same native stack until the (very stack-hungry) Adreno GL driver overflowed the thread. The callback now only flags a pending frame; a separate PostOnAnimation loop drives Render()/RunOnce(), mirroring the Windows controller.
  • Android: touch gestures did nothing (only the on-screen buttons worked)RotateGesturesEnabled / ScrollGesturesEnabled / TiltGesturesEnabled / ZoomGesturesEnabled were declared without a default, so they defaulted to false and MAUI's initial property sync disabled all gesture input at startup. They now default to true.
  • Android: panning was far slower than the finger, and pinch anchored to the wrong point — touch screen-coordinates (pan delta, pinch focus, tap position, rotate pivot) were divided by the display's pixel ratio before being handed to the native map, which uses the same raw device-pixel space as SetSize. On a high-density/scaled screen a full-width drag panned only a fraction of the map. The redundant division was removed.
  • Android: polygon fills rendered as a checkerboard and tiles showed white seams — the EGL config requested no depth or stencil buffer, but mbgl-core's fill-layer renderer needs the stencil buffer for polygon tessellation and tile-boundary clipping (Windows already requests a depth/stencil pixel format). EGL_DEPTH_SIZE, 24 and EGL_STENCIL_SIZE, 8 are now requested.
  • Android: map content stretched/squished (or blanked) after rotating the deviceRendererBackend::assumeViewport() only updates mbgl-core's cached viewport; it never calls glViewport(). Since the GL viewport is context state (not surface state) it never reset on resize, so the hardware viewport stayed frozen at its first-frame value and content kept rasterizing through the stale rectangle. The Android backend now issues a real glViewport() in updateAssumedState() (and recreates the EGL surface on size changes), keeping the viewport honest across rotations and tab switches.
  • Android: tiles stopped refreshing when zooming in (stuck on lower-zoom content) — the C# HttpClient tile provider never cancelled requests mbgl superseded, so they ran to completion and starved the connection pool of slots for the tiles actually needed at the new zoom. The provider protocol gained a cancel callback (mbgl_set_http_cancel_provider) so superseded fetches are aborted and their connections freed. Only affected Android (Windows uses mbgl-core's built-in native HTTP).