Bug 1052253 - Part 2: Map macOS pinch zoom gesture to wheel event with control key. r=mstange

This patch matches Chrome's behavior almost exactly, except it uses a slightly
different formula for the deltaY value that results in the same movement speed
as Chrome but doesn't drift over time.

Tested by confirming that trackpad pinch zoom now works on maps.google.com,
wego.here.com, and figma.com.
This commit is contained in:
Evan Wallace 2017-05-12 15:39:09 +03:00
Родитель 0e52c9ca9e
Коммит 8c715c91e6
1 изменённых файлов: 33 добавлений и 8 удалений

Просмотреть файл

@ -4243,16 +4243,41 @@ NSEvent* gLastDragMouseDownEvent = nil;
return;
}
// Setup the event.
WidgetSimpleGestureEvent geckoEvent(true, msg, mGeckoChild);
geckoEvent.mDelta = deltaZ;
[self convertCocoaMouseEvent:anEvent toGeckoEvent:&geckoEvent];
// This sends the pinch gesture value as a fake wheel event that has the
// control key pressed so that pages can implement custom pinch gesture
// handling. It may seem strange that this doesn't use a wheel event with
// the deltaZ property set, but this matches Chrome's behavior as described
// at https://code.google.com/p/chromium/issues/detail?id=289887
//
// The intent of the formula below is to produce numbers similar to Chrome's
// implementation of this feature. Chrome implements deltaY using the formula
// "-100 * log(1 + [event magnification])" which is unfortunately incorrect.
// All deltas for a single pinch gesture should sum to 0 if the start and end
// of a pinch gesture end up in the same place. This doesn't happen in Chrome
// because they followed Apple's misleading documentation, which implies that
// "1 + [event magnification]" is the scale factor. The scale factor is
// instead "pow(ratio, [event magnification])" so "[event magnification]" is
// already in log space.
//
// The multiplication by the backing scale factor below counteracts the
// division by the backing scale factor in WheelEvent.
WidgetWheelEvent geckoWheelEvent(true, EventMessage::eWheel, mGeckoChild);
[self convertCocoaMouseEvent:anEvent toGeckoEvent:&geckoWheelEvent];
double backingScale = mGeckoChild->BackingScaleFactor();
geckoWheelEvent.mDeltaY = -100.0 * [anEvent magnification] * backingScale;
geckoWheelEvent.mModifiers |= MODIFIER_CONTROL;
mGeckoChild->DispatchWindowEvent(geckoWheelEvent);
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
// If the fake wheel event wasn't stopped, then send a normal magnify event.
if (!geckoWheelEvent.mFlags.mDefaultPrevented) {
WidgetSimpleGestureEvent geckoEvent(true, msg, mGeckoChild);
geckoEvent.mDelta = deltaZ;
[self convertCocoaMouseEvent:anEvent toGeckoEvent:&geckoEvent];
mGeckoChild->DispatchWindowEvent(geckoEvent);
// Keep track of the cumulative magnification for the final "magnify" event.
mCumulativeMagnification += deltaZ;
// Keep track of the cumulative magnification for the final "magnify" event.
mCumulativeMagnification += deltaZ;
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}