Bug 1133629 - IMEContentObserver should grab itself before using ContentEventHandler because it causes flushing pending layout. r=smaug, a=sledru
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 17 Feb 2015 22:20:08 +0900
changeset 245436 f753656b2806
parent 245435 3cd0f44138da
child 245437 b20bd6385474
push id673
push userryanvm@gmail.com
push date2015-03-02 20:00 +0000
treeherdermozilla-release@608bab8e4868 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, sledru
bugs1133629
milestone36.0
Bug 1133629 - IMEContentObserver should grab itself before using ContentEventHandler because it causes flushing pending layout. r=smaug, a=sledru
dom/events/IMEContentObserver.cpp
--- a/dom/events/IMEContentObserver.cpp
+++ b/dom/events/IMEContentObserver.cpp
@@ -425,30 +425,38 @@ IMEContentObserver::OnMouseButtonEvent(n
   // Now, we need to notify only mouse down and mouse up event.
   switch (aMouseEvent->message) {
     case NS_MOUSE_BUTTON_UP:
     case NS_MOUSE_BUTTON_DOWN:
       break;
     default:
       return false;
   }
-  if (NS_WARN_IF(!mWidget)) {
+  if (NS_WARN_IF(!mWidget) || NS_WARN_IF(mWidget->Destroyed())) {
     return false;
   }
 
+  nsRefPtr<IMEContentObserver> kungFuDeathGrip(this);
+
   WidgetQueryContentEvent charAtPt(true, NS_QUERY_CHARACTER_AT_POINT,
                                    aMouseEvent->widget);
   charAtPt.refPoint = aMouseEvent->refPoint;
   ContentEventHandler handler(aPresContext);
   handler.OnQueryCharacterAtPoint(&charAtPt);
   if (NS_WARN_IF(!charAtPt.mSucceeded) ||
       charAtPt.mReply.mOffset == WidgetQueryContentEvent::NOT_FOUND) {
     return false;
   }
 
+  // The widget might be destroyed during querying the content since it
+  // causes flushing layout.
+  if (!mWidget || NS_WARN_IF(mWidget->Destroyed())) {
+    return false;
+  }
+
   // The result character rect is relative to the top level widget.
   // We should notify it with offset in the widget.
   nsIWidget* topLevelWidget = mWidget->GetTopLevelWidget();
   if (topLevelWidget && topLevelWidget != mWidget) {
     charAtPt.mReply.mRect.MoveBy(
       topLevelWidget->WidgetToScreenOffset() -
         mWidget->WidgetToScreenOffset());
   }