Bug 1280428 - Hold a strong pointer to the nsChildView while dispatching events (speculative crash fix). r=mstange
MozReview-Commit-ID: FPnCu0zqVjr
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -4874,16 +4874,21 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
forEvent:theEvent];
} else if (phase & (NSEventPhaseEnded | NSEventPhaseCancelled)) {
[self sendWheelCondition:NO
first:eWheelOperationStart
second:eWheelOperationEnd
forEvent:theEvent];
}
+ if (!mGeckoChild) {
+ return;
+ }
+ RefPtr<nsChildView> geckoChildDeathGrip(mGeckoChild);
+
NSPoint locationInWindow = nsCocoaUtils::EventLocationForWindow(theEvent, [self window]);
ScreenPoint position = ViewAs<ScreenPixel>(
[self convertWindowCoordinates:locationInWindow],
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
bool usePreciseDeltas = nsCocoaUtils::HasPreciseScrollingDeltas(theEvent) &&
Preferences::GetBool("mousewheel.enable_pixel_scrolling", true);
@@ -4896,17 +4901,17 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
NSTimeInterval beforeNow = [[NSProcessInfo processInfo] systemUptime] - [theEvent timestamp];
PRIntervalTime eventIntervalTime = PR_IntervalNow() - PR_MillisecondsToInterval(beforeNow * 1000);
TimeStamp eventTimeStamp = TimeStamp::Now() - TimeDuration::FromSeconds(beforeNow);
ScreenPoint preciseDelta;
if (usePreciseDeltas) {
CGFloat pixelDeltaX = 0, pixelDeltaY = 0;
nsCocoaUtils::GetScrollingDeltas(theEvent, &pixelDeltaX, &pixelDeltaY);
- double scale = mGeckoChild->BackingScaleFactor();
+ double scale = geckoChildDeathGrip->BackingScaleFactor();
preciseDelta = ScreenPoint(-pixelDeltaX * scale, -pixelDeltaY * scale);
}
if (usePreciseDeltas && hasPhaseInformation) {
PanGestureInput panEvent(PanGestureTypeForEvent(theEvent),
eventIntervalTime, eventTimeStamp,
position, preciseDelta, modifiers);
panEvent.mLineOrPageDeltaX = lineOrPageDelta.x;
@@ -4923,45 +4928,45 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
if (nextWheelEvent &&
PanGestureTypeForEvent(nextWheelEvent) == PanGestureInput::PANGESTURE_MOMENTUMSTART) {
panEvent.mFollowedByMomentum = true;
}
}
bool canTriggerSwipe = [self shouldConsiderStartingSwipeFromEvent:theEvent];
panEvent.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection = canTriggerSwipe;
- mGeckoChild->DispatchAPZWheelInputEvent(panEvent, canTriggerSwipe);
+ geckoChildDeathGrip->DispatchAPZWheelInputEvent(panEvent, canTriggerSwipe);
} else if (usePreciseDeltas) {
// This is on 10.6 or old touchpads that don't have any phase information.
ScrollWheelInput wheelEvent(eventIntervalTime, eventTimeStamp, modifiers,
ScrollWheelInput::SCROLLMODE_INSTANT,
ScrollWheelInput::SCROLLDELTA_PIXEL,
position,
preciseDelta.x,
preciseDelta.y,
false);
wheelEvent.mLineOrPageDeltaX = lineOrPageDelta.x;
wheelEvent.mLineOrPageDeltaY = lineOrPageDelta.y;
wheelEvent.mIsMomentum = nsCocoaUtils::IsMomentumScrollEvent(theEvent);
- mGeckoChild->DispatchAPZWheelInputEvent(wheelEvent, false);
+ geckoChildDeathGrip->DispatchAPZWheelInputEvent(wheelEvent, false);
} else {
ScrollWheelInput::ScrollMode scrollMode = ScrollWheelInput::SCROLLMODE_INSTANT;
if (gfxPrefs::SmoothScrollEnabled() && gfxPrefs::WheelSmoothScrollEnabled()) {
scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
}
ScrollWheelInput wheelEvent(eventIntervalTime, eventTimeStamp, modifiers,
scrollMode,
ScrollWheelInput::SCROLLDELTA_LINE,
position,
lineOrPageDelta.x,
lineOrPageDelta.y,
false);
wheelEvent.mLineOrPageDeltaX = lineOrPageDelta.x;
wheelEvent.mLineOrPageDeltaY = lineOrPageDelta.y;
- mGeckoChild->DispatchAPZWheelInputEvent(wheelEvent, false);
+ geckoChildDeathGrip->DispatchAPZWheelInputEvent(wheelEvent, false);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)handleAsyncScrollEvent:(CGEventRef)cgEvent ofType:(CGEventType)type
{
IAPZCTreeManager* apzctm = [self apzctm];