Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit fcbd2b7

Browse files
committed
Workaround for magic mouse events which happen to be divisible by 120.
1 parent 55505af commit fcbd2b7

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

lib/web_ui/lib/src/engine/pointer_binding.dart

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ abstract class _BaseAdapter {
263263
final _PointerDataCallback _callback;
264264
final PointerDataConverter _pointerDataConverter;
265265
final KeyboardConverter _keyboardConverter;
266+
DomWheelEvent? _lastWheelEvent;
266267

267268
/// Each subclass is expected to override this method to attach its own event
268269
/// listeners and convert events into pointer events.
@@ -348,7 +349,7 @@ mixin _WheelEventListenerMixin on _BaseAdapter {
348349
return (wheelDelta - (-3 * delta)).abs() > 1;
349350
}
350351

351-
bool _isTrackpadEvent(DomWheelEvent event) {
352+
bool _isTrackpadEvent(DomWheelEvent event, DomWheelEvent? lastWheelEvent) {
352353
// This function relies on deprecated and non-standard implementation
353354
// details. Useful reference material can be found below.
354355
//
@@ -366,9 +367,17 @@ mixin _WheelEventListenerMixin on _BaseAdapter {
366367
if ((event.deltaX % 120 == 0) && (event.deltaY % 120 == 0)) {
367368
// While not in any formal web standard, `blink` and `webkit` browsers use
368369
// a delta of 120 to represent one mouse wheel turn. If both dimensions of
369-
// the delta are divisible by 120, this event is almost certainly not from
370-
// a trackpad.
371-
return false;
370+
// the delta are divisible by 120, this event is probably from a mouse.
371+
final num deltaXChange = (event.deltaX - (lastWheelEvent?.deltaX ?? 0)).abs();
372+
final num deltaYChange = (event.deltaY - (lastWheelEvent?.deltaY ?? 0)).abs();
373+
if ((lastWheelEvent == null) ||
374+
(deltaXChange == 0 && deltaYChange == 0) ||
375+
!(deltaXChange < 10 && deltaYChange < 10)) {
376+
// A trackpad event might by chance have a delta of exactly 120, so
377+
// make sure this event does not have a similar delta to the previous
378+
// one before calling it a mouse event.
379+
return false;
380+
}
372381
}
373382
if (_isAcceleratedMouseWheelDelta(event.deltaX, event.wheelDeltaX) ||
374383
_isAcceleratedMouseWheelDelta(event.deltaY, event.wheelDeltaY)) {
@@ -385,7 +394,7 @@ mixin _WheelEventListenerMixin on _BaseAdapter {
385394
const int domDeltaPage = 0x02;
386395

387396
ui.PointerDeviceKind kind = ui.PointerDeviceKind.mouse;
388-
if (_isTrackpadEvent(event)) {
397+
if (_isTrackpadEvent(event, _lastWheelEvent)) {
389398
kind = ui.PointerDeviceKind.trackpad;
390399
}
391400

@@ -431,6 +440,7 @@ mixin _WheelEventListenerMixin on _BaseAdapter {
431440
scrollDeltaX: deltaX,
432441
scrollDeltaY: deltaY,
433442
);
443+
_lastWheelEvent = event;
434444
return data;
435445
}
436446

lib/web_ui/test/engine/pointer_binding_test.dart

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,22 +1169,32 @@ void testMain() {
11691169
buttons: 0,
11701170
clientX: 10,
11711171
clientY: 10,
1172-
deltaX: 10,
1173-
deltaY: 10,
1174-
wheelDeltaX: -30,
1175-
wheelDeltaY: -30,
1172+
deltaX: 119,
1173+
deltaY: 119,
1174+
wheelDeltaX: -357,
1175+
wheelDeltaY: -357,
11761176
));
11771177

11781178
glassPane.dispatchEvent(context.wheel(
11791179
buttons: 0,
11801180
clientX: 10,
11811181
clientY: 10,
1182-
deltaX: 0,
1182+
deltaX: 120,
11831183
deltaY: 120,
1184-
wheelDeltaX: 0,
1184+
wheelDeltaX: -360,
11851185
wheelDeltaY: -360,
11861186
));
11871187

1188+
glassPane.dispatchEvent(context.wheel(
1189+
buttons: 0,
1190+
clientX: 10,
1191+
clientY: 10,
1192+
deltaX: 0,
1193+
deltaY: -120,
1194+
wheelDeltaX: 0,
1195+
wheelDeltaY: 360,
1196+
));
1197+
11881198
glassPane.dispatchEvent(context.wheel(
11891199
buttons: 0,
11901200
clientX: 10,
@@ -1195,7 +1205,7 @@ void testMain() {
11951205
wheelDeltaY: -360,
11961206
));
11971207

1198-
expect(packets, hasLength(3));
1208+
expect(packets, hasLength(4));
11991209

12001210
// An add will be synthesized.
12011211
expect(packets[0].data, hasLength(2));
@@ -1219,27 +1229,27 @@ void testMain() {
12191229
expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
12201230
expect(packets[0].data[1].physicalDeltaX, equals(0.0));
12211231
expect(packets[0].data[1].physicalDeltaY, equals(0.0));
1222-
expect(packets[0].data[1].scrollDeltaX, equals(10.0));
1223-
expect(packets[0].data[1].scrollDeltaY, equals(10.0));
1232+
expect(packets[0].data[1].scrollDeltaX, equals(119.0));
1233+
expect(packets[0].data[1].scrollDeltaY, equals(119.0));
12241234

1225-
// Because the delta is in increments of 120, it will be a mouse event.
1226-
expect(packets[1].data, hasLength(1));
1235+
// Because the delta is in increments of 120, but is similar to the
1236+
// previous event, it will be a trackpad event.
12271237
expect(packets[1].data[0].change, equals(ui.PointerChange.hover));
12281238
expect(
12291239
packets[1].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
12301240
expect(
1231-
packets[1].data[0].kind, equals(ui.PointerDeviceKind.mouse));
1241+
packets[1].data[0].kind, equals(ui.PointerDeviceKind.trackpad));
12321242
expect(packets[1].data[0].pointerIdentifier, equals(0));
12331243
expect(packets[1].data[0].synthesized, isFalse);
12341244
expect(packets[1].data[0].physicalX, equals(10.0 * dpi));
12351245
expect(packets[1].data[0].physicalY, equals(10.0 * dpi));
12361246
expect(packets[1].data[0].physicalDeltaX, equals(0.0));
12371247
expect(packets[1].data[0].physicalDeltaY, equals(0.0));
1238-
expect(packets[1].data[0].scrollDeltaX, equals(0.0));
1248+
expect(packets[1].data[0].scrollDeltaX, equals(120.0));
12391249
expect(packets[1].data[0].scrollDeltaY, equals(120.0));
12401250

1241-
// Because the delta is not in increments of 120 and has non-matching
1242-
// wheelDelta, it will be a mouse event.
1251+
// Because the delta is in increments of 120, and is not similar to
1252+
// the previous event, it will be a mouse event.
12431253
expect(packets[2].data, hasLength(1));
12441254
expect(packets[2].data[0].change, equals(ui.PointerChange.hover));
12451255
expect(
@@ -1253,7 +1263,24 @@ void testMain() {
12531263
expect(packets[2].data[0].physicalDeltaX, equals(0.0));
12541264
expect(packets[2].data[0].physicalDeltaY, equals(0.0));
12551265
expect(packets[2].data[0].scrollDeltaX, equals(0.0));
1256-
expect(packets[2].data[0].scrollDeltaY, equals(40.0));
1266+
expect(packets[2].data[0].scrollDeltaY, equals(-120.0));
1267+
1268+
// Because the delta is not in increments of 120 and has non-matching
1269+
// wheelDelta, it will be a mouse event.
1270+
expect(packets[3].data, hasLength(1));
1271+
expect(packets[3].data[0].change, equals(ui.PointerChange.hover));
1272+
expect(
1273+
packets[3].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
1274+
expect(
1275+
packets[3].data[0].kind, equals(ui.PointerDeviceKind.mouse));
1276+
expect(packets[3].data[0].pointerIdentifier, equals(0));
1277+
expect(packets[3].data[0].synthesized, isFalse);
1278+
expect(packets[3].data[0].physicalX, equals(10.0 * dpi));
1279+
expect(packets[3].data[0].physicalY, equals(10.0 * dpi));
1280+
expect(packets[3].data[0].physicalDeltaX, equals(0.0));
1281+
expect(packets[3].data[0].physicalDeltaY, equals(0.0));
1282+
expect(packets[3].data[0].scrollDeltaX, equals(0.0));
1283+
expect(packets[3].data[0].scrollDeltaY, equals(40.0));
12571284
},
12581285
);
12591286

0 commit comments

Comments
 (0)