From c00a30b01476f08c341456601af5637831fcfe93 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Tue, 30 Jul 2024 19:38:15 +0200 Subject: [PATCH] Allow pinch trackpad gesture while cooperative gestures is enabled (#4465) * Allow pinch trackpad gesture while cooperative gestures is enabled * Add changelog entry * Fix linting * Update test size expectation --- CHANGELOG.md | 2 ++ src/ui/handler/cooperative_gestures.test.ts | 33 +++++++++++++++++++++ src/ui/handler/cooperative_gestures.ts | 15 +++++++++- src/ui/handler/scroll_zoom.ts | 2 +- test/build/min.test.ts | 4 +-- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a676a9980e..0ec51b6a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## main +- Allow trackpad pinch gestures to break through the `cooperativeGestures` setting, bringing it in line with other embedded map behaviours, such as Google Maps and Mapbox. ([#4465](https://github.com/maplibre/maplibre-gl-js/pull/4465)) + ### ✨ Features and improvements - Expose projection matrix parameters ([#3136](https://github.com/maplibre/maplibre-gl-js/pull/3136)) diff --git a/src/ui/handler/cooperative_gestures.test.ts b/src/ui/handler/cooperative_gestures.test.ts index 4320de2f11..b6f5861c9a 100644 --- a/src/ui/handler/cooperative_gestures.test.ts +++ b/src/ui/handler/cooperative_gestures.test.ts @@ -97,6 +97,39 @@ describe('CoopGesturesHandler', () => { map.remove(); }); + test('Zooms on trackpad pinch when metaKey is the bypass key', () => { + // NOTE: This should pass regardless of whether cooperativeGestures is enabled or not + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(true); + + // pretend we're on a Mac, where the ctrlKey isn't the bypassKey + map.cooperativeGestures._bypassKey = 'metaKey'; + map._renderTaskQueue.run(); + + const startZoom = map.getZoom(); + // simulate a single 'wheel' trackpad pinch event + simulate.wheel(map.getCanvas(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + + // this is how a browser identifies a trackpad pinch + ctrlKey: true + }); + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + + const endZoom = map.getZoom(); + expect(endZoom - startZoom).toBeCloseTo(0.0285, 3); + + map.remove(); + }); + test('Does not show message if scrollZoom is disabled', () => { // NOTE: This should pass regardless of whether cooperativeGestures is enabled or not const browserNow = jest.spyOn(browser, 'now'); diff --git a/src/ui/handler/cooperative_gestures.ts b/src/ui/handler/cooperative_gestures.ts index 2af9786101..9fe8eee3fb 100644 --- a/src/ui/handler/cooperative_gestures.ts +++ b/src/ui/handler/cooperative_gestures.ts @@ -97,7 +97,20 @@ export class CooperativeGesturesHandler implements Handler { if (!this._map.scrollZoom.isEnabled()) { return; } - this._onCooperativeGesture(!e[this._bypassKey]); + + const isPrevented = this.shouldPreventWheelEvent(e); + this._onCooperativeGesture(isPrevented); + } + + shouldPreventWheelEvent(e: WheelEvent) { + if (!this.isEnabled()) { + return false; + } + + const isTrackpadPinch = e.ctrlKey; + const isBypassed = e[this._bypassKey] || isTrackpadPinch; + + return !isBypassed; } _onCooperativeGesture(showNotification: boolean) { diff --git a/src/ui/handler/scroll_zoom.ts b/src/ui/handler/scroll_zoom.ts index 56ecfefefd..095f337175 100644 --- a/src/ui/handler/scroll_zoom.ts +++ b/src/ui/handler/scroll_zoom.ts @@ -151,7 +151,7 @@ export class ScrollZoomHandler implements Handler { wheel(e: WheelEvent) { if (!this.isEnabled()) return; - if (this._map.cooperativeGestures.isEnabled() && !e[this._map.cooperativeGestures._bypassKey]) { + if (this._map.cooperativeGestures.shouldPreventWheelEvent(e)) { return; } let value = e.deltaMode === WheelEvent.DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY; diff --git a/test/build/min.test.ts b/test/build/min.test.ts index 8cc9002488..b0d0fd23f0 100644 --- a/test/build/min.test.ts +++ b/test/build/min.test.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import packageJson from '../../package.json' with {type: 'json'}; +import packageJson from '../../package.json' with { type: 'json' }; const minBundle = fs.readFileSync('dist/maplibre-gl.js', 'utf8'); @@ -36,7 +36,7 @@ describe('test min build', () => { const decreaseQuota = 4096; // feel free to update this value after you've checked that it has changed on purpose :-) - const expectedBytes = 799999; + const expectedBytes = 800300; expect(actualBytes - expectedBytes).toBeLessThan(increaseQuota); expect(expectedBytes - actualBytes).toBeLessThan(decreaseQuota);