Bug 664707. Special case converting event coordinates when the frame is the root frame in the widget. r=matspal
authorTimothy Nikkel <tnikkel@gmail.com>
Sat, 03 Mar 2012 15:24:13 -0600
changeset 88415 9fbe111ef1c3e274ff99884cbbcfc8555aa4f595
parent 88414 c51dbd19871b64531b2e24d1bbebb6fe3d35e29f
child 88416 110d4d8841864168918a154f4ace281b130e4b4a
push id157
push userMs2ger@gmail.com
push dateWed, 07 Mar 2012 19:27:10 +0000
reviewersmatspal
bugs664707
milestone13.0a1
Bug 664707. Special case converting event coordinates when the frame is the root frame in the widget. r=matspal This has the side benefit of making events work in transformed select dropdown popups and is the real reason for making the change.
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -968,16 +968,31 @@ nsLayoutUtils::GetEventCoordinatesRelati
   const nsGUIEvent* GUIEvent = static_cast<const nsGUIEvent*>(aEvent);
 #ifdef MOZ_TOUCH
   return GetEventCoordinatesRelativeTo(aEvent,
                                        GUIEvent->refPoint,
                                        aFrame);
 #else
   if (!GUIEvent->widget)
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+
+  nsIView* view = aFrame->GetView();
+  if (view) {
+    nsIWidget* widget = view->GetWidget();
+    if (widget && widget == GUIEvent->widget) {
+      // Special case this cause it happens a lot.
+      // This also fixes bug 664707, events in the extra-special case of select
+      // dropdown popups that are transformed.
+      nsPresContext* presContext = aFrame->PresContext();
+      nsPoint pt(presContext->DevPixelsToAppUnits(GUIEvent->refPoint.x),
+                 presContext->DevPixelsToAppUnits(GUIEvent->refPoint.y));
+      return pt - view->ViewToWidgetOffset();
+    }
+  }
+
   /* If we walk up the frame tree and discover that any of the frames are
    * transformed, we need to do extra work to convert from the global
    * space to the local space.
    */
   nsIFrame* rootFrame = aFrame;
   bool transformFound = false;
 
   for (nsIFrame* f = aFrame; f; f = GetCrossDocParentFrame(f)) {
@@ -1026,16 +1041,30 @@ nsLayoutUtils::GetEventCoordinatesRelati
   }
 
   const nsGUIEvent* GUIEvent = static_cast<const nsGUIEvent*>(aEvent);
   nsIWidget* widget = GUIEvent->widget;
   if (!widget) {
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
   }
 
+  nsIView* view = aFrame->GetView();
+  if (view) {
+    nsIWidget* fwidget = view->GetWidget();
+    if (fwidget && fwidget == GUIEvent->widget) {
+      // Special case this cause it happens a lot.
+      // This also fixes bug 664707, events in the extra-special case of select
+      // dropdown popups that are transformed.
+      nsPresContext* presContext = aFrame->PresContext();
+      nsPoint pt(presContext->DevPixelsToAppUnits(GUIEvent->refPoint.x),
+                 presContext->DevPixelsToAppUnits(GUIEvent->refPoint.y));
+      return pt - view->ViewToWidgetOffset();
+    }
+  }
+
   /* If we walk up the frame tree and discover that any of the frames are
    * transformed, we need to do extra work to convert from the global
    * space to the local space.
    */
   nsIFrame* rootFrame = aFrame;
   bool transformFound = false;
   for (nsIFrame* f = aFrame; f; f = GetCrossDocParentFrame(f)) {
     if (f->IsTransformed()) {