From 8d6c1ad0bbf12c550d2c91b66593d363ee8cf3bb Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Tue, 16 Aug 2022 14:42:43 +0200 Subject: [PATCH 1/2] Convert Safari and Firefox wheel delta to physical pixels. This makes it consistent with Chrome and partially fixes https://github.com/flutter/flutter/issues/75850 --- lib/web_ui/lib/src/engine/pointer_binding.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/web_ui/lib/src/engine/pointer_binding.dart b/lib/web_ui/lib/src/engine/pointer_binding.dart index a41b550c5fd8a..3d2fc21246be1 100644 --- a/lib/web_ui/lib/src/engine/pointer_binding.dart +++ b/lib/web_ui/lib/src/engine/pointer_binding.dart @@ -339,6 +339,14 @@ mixin _WheelEventListenerMixin on _BaseAdapter { deltaY *= ui.window.physicalSize.height; break; case domDeltaPixel: + if (operatingSystem == OperatingSystem.macOs && + browserEngine != BrowserEngine.blink) { + // Safari and Firefox seems to report delta in logical pixels while + // Chrome uses physical pixels. + deltaX *= ui.window.devicePixelRatio; + deltaY *= ui.window.devicePixelRatio; + } + break; default: break; } From 8c2a62e839d75eea7c97d8d9c8fbbbd1629d93c8 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Thu, 29 Sep 2022 14:37:36 -0400 Subject: [PATCH 2/2] add tests --- .../lib/src/engine/pointer_binding.dart | 5 +- .../test/engine/pointer_binding_test.dart | 106 +++++++++++++++++- 2 files changed, 102 insertions(+), 9 deletions(-) diff --git a/lib/web_ui/lib/src/engine/pointer_binding.dart b/lib/web_ui/lib/src/engine/pointer_binding.dart index 3d2fc21246be1..75ad7b4387d4d 100644 --- a/lib/web_ui/lib/src/engine/pointer_binding.dart +++ b/lib/web_ui/lib/src/engine/pointer_binding.dart @@ -339,9 +339,8 @@ mixin _WheelEventListenerMixin on _BaseAdapter { deltaY *= ui.window.physicalSize.height; break; case domDeltaPixel: - if (operatingSystem == OperatingSystem.macOs && - browserEngine != BrowserEngine.blink) { - // Safari and Firefox seems to report delta in logical pixels while + if (operatingSystem == OperatingSystem.macOs && (isSafari || isFirefox)) { + // Safari and Firefox seem to report delta in logical pixels while // Chrome uses physical pixels. deltaX *= ui.window.devicePixelRatio; deltaY *= ui.window.devicePixelRatio; diff --git a/lib/web_ui/test/engine/pointer_binding_test.dart b/lib/web_ui/test/engine/pointer_binding_test.dart index 44ff17a0017e9..130c53f33e740 100644 --- a/lib/web_ui/test/engine/pointer_binding_test.dart +++ b/lib/web_ui/test/engine/pointer_binding_test.dart @@ -6,11 +6,7 @@ import 'dart:js_util' as js_util; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; -import 'package:ui/src/engine.dart' show flutterViewEmbedder, window; -import 'package:ui/src/engine/browser_detection.dart'; -import 'package:ui/src/engine/dom.dart'; -import 'package:ui/src/engine/embedder.dart'; -import 'package:ui/src/engine/pointer_binding.dart'; +import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; const int _kNoButtonChange = -1; @@ -43,7 +39,7 @@ void main() { void testMain() { ensureFlutterViewEmbedderInitialized(); final DomElement glassPane = flutterViewEmbedder.glassPaneElement!; - double dpi = 1.0; + late double dpi; setUp(() { ui.window.onPointerDataPacket = null; @@ -726,6 +722,104 @@ void testMain() { }, ); + _testEach<_ButtonedEventMixin>( + <_ButtonedEventMixin>[ + if (!isIosSafari) _PointerEventContext(), + if (!isIosSafari) _MouseEventContext(), + ], + 'converts scroll delta to physical pixels (Firefox)', + (_ButtonedEventMixin context) { + PointerBinding.instance!.debugOverrideDetector(context); + + const double dpi = 2.5; + debugOperatingSystemOverride = OperatingSystem.macOs; + debugBrowserEngineOverride = BrowserEngine.firefox; + window.debugOverrideDevicePixelRatio(dpi); + + final List packets = []; + ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) { + packets.add(packet); + }; + + glassPane.dispatchEvent(context.wheel( + buttons: 0, + clientX: 10, + clientY: 10, + deltaX: 10, + deltaY: 10, + )); + + expect(packets, hasLength(1)); + + + // An add will be synthesized. + expect(packets[0].data, hasLength(2)); + expect(packets[0].data[0].change, equals(ui.PointerChange.add)); + // Scroll deltas should be multiplied by `dpi`. + expect(packets[0].data[0].scrollDeltaX, equals(10.0 * dpi)); + expect(packets[0].data[0].scrollDeltaY, equals(10.0 * dpi)); + + expect(packets[0].data[1].change, equals(ui.PointerChange.hover)); + expect(packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll)); + // Scroll deltas should be multiplied by `dpi`. + expect(packets[0].data[0].scrollDeltaX, equals(10.0 * dpi)); + expect(packets[0].data[0].scrollDeltaY, equals(10.0 * dpi)); + + window.debugOverrideDevicePixelRatio(1.0); + debugOperatingSystemOverride = null; + debugBrowserEngineOverride = null; + }, + ); + + _testEach<_ButtonedEventMixin>( + <_ButtonedEventMixin>[ + if (!isIosSafari) _PointerEventContext(), + if (!isIosSafari) _MouseEventContext(), + ], + 'scroll delta are already in physical pixels (Chrome)', + (_ButtonedEventMixin context) { + PointerBinding.instance!.debugOverrideDetector(context); + + const double dpi = 2.5; + debugOperatingSystemOverride = OperatingSystem.macOs; + debugBrowserEngineOverride = BrowserEngine.blink; + window.debugOverrideDevicePixelRatio(dpi); + + final List packets = []; + ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) { + packets.add(packet); + }; + + glassPane.dispatchEvent(context.wheel( + buttons: 0, + clientX: 10, + clientY: 10, + deltaX: 10, + deltaY: 10, + )); + + expect(packets, hasLength(1)); + + + // An add will be synthesized. + expect(packets[0].data, hasLength(2)); + expect(packets[0].data[0].change, equals(ui.PointerChange.add)); + // Scroll deltas should NOT be multiplied by `dpi`. + expect(packets[0].data[0].scrollDeltaX, equals(10.0)); + expect(packets[0].data[0].scrollDeltaY, equals(10.0)); + + expect(packets[0].data[1].change, equals(ui.PointerChange.hover)); + expect(packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll)); + // Scroll deltas should NOT be multiplied by `dpi`. + expect(packets[0].data[0].scrollDeltaX, equals(10.0)); + expect(packets[0].data[0].scrollDeltaY, equals(10.0)); + + window.debugOverrideDevicePixelRatio(1.0); + debugOperatingSystemOverride = null; + debugBrowserEngineOverride = null; + }, + ); + _testEach<_ButtonedEventMixin>( <_ButtonedEventMixin>[ if (!isIosSafari) _PointerEventContext(),