diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index c59eea4d254..56d16b7d013 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -655,20 +655,47 @@ nsLayoutUtils::GetEventCoordinatesForNearestView(nsEvent* aEvent, GUIEvent->refPoint, frameView); } +static nsPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { + nsPoint offset(0, 0); + nsIWidget* parent = aWidget->GetParent(); + while (parent) { + nsRect bounds; + aWidget->GetBounds(bounds); + offset += bounds.TopLeft(); + aWidget = parent; + parent = aWidget->GetParent(); + } + aRootWidget = aWidget; + return offset; +} + nsPoint nsLayoutUtils::TranslateWidgetToView(nsPresContext* aPresContext, nsIWidget* aWidget, nsIntPoint aPt, nsIView* aView) { - nsIView* baseView = nsIView::GetViewFor(aWidget); - if (!baseView) - return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - nsPoint viewToWidget; - nsIWidget* wid = baseView->GetNearestWidget(&viewToWidget); - NS_ASSERTION(aWidget == wid, "Clashing widgets"); - nsPoint refPointAppUnits(aPresContext->DevPixelsToAppUnits(aPt.x), - aPresContext->DevPixelsToAppUnits(aPt.y)); - return refPointAppUnits - viewToWidget - aView->GetOffsetTo(baseView); + nsPoint viewOffset; + nsIWidget* viewWidget = aView->GetNearestWidget(&viewOffset); + + nsIWidget* fromRoot; + nsPoint fromOffset = GetWidgetOffset(aWidget, fromRoot); + nsIWidget* toRoot; + nsPoint toOffset = GetWidgetOffset(viewWidget, toRoot); + + nsIntPoint widgetPoint; + if (fromRoot == toRoot) { + widgetPoint = aPt + fromOffset - toOffset; + } else { + nsIntRect widgetRect(0, 0, 0, 0); + nsIntRect screenRect; + aWidget->WidgetToScreen(widgetRect, screenRect); + viewWidget->ScreenToWidget(screenRect, widgetRect); + widgetPoint = aPt + widgetRect.TopLeft(); + } + + nsPoint widgetAppUnits(aPresContext->DevPixelsToAppUnits(widgetPoint.x), + aPresContext->DevPixelsToAppUnits(widgetPoint.y)); + return widgetAppUnits - viewOffset; } // Combine aNewBreakType with aOrigBreakType, but limit the break types