Bug 1754662. Refactor nsLayoutUtils::GetPopupFrameForEventCoordinates. r=emilio

This lets us re-use code for bug 1754436.

Differential Revision: https://phabricator.services.mozilla.com/D138392
This commit is contained in:
Timothy Nikkel 2022-02-12 09:41:50 +00:00
parent 3f972b34cb
commit 6917164039
4 changed files with 54 additions and 29 deletions

View File

@ -511,13 +511,10 @@ LocalAccessible* LocalAccessible::LocalChildAtPoint(
LayoutDeviceIntRect rootRect = rootWidget->GetScreenBounds();
WidgetMouseEvent dummyEvent(true, eMouseMove, rootWidget,
WidgetMouseEvent::eSynthesized);
dummyEvent.mRefPoint =
LayoutDeviceIntPoint(aX - rootRect.X(), aY - rootRect.Y());
auto point = LayoutDeviceIntPoint(aX - rootRect.X(), aY - rootRect.Y());
nsIFrame* popupFrame = nsLayoutUtils::GetPopupFrameForEventCoordinates(
accDocument->PresContext()->GetRootPresContext(), &dummyEvent);
nsIFrame* popupFrame = nsLayoutUtils::GetPopupFrameForPoint(
accDocument->PresContext()->GetRootPresContext(), rootWidget, point);
if (popupFrame) {
// If 'this' accessible is not inside the popup then ignore the popup when
// searching an accessible at point.

View File

@ -2378,11 +2378,8 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, int64_t aOffset,
if (message == eQueryCharacterAtPoint) {
// Looking for the widget at the point.
WidgetQueryContentEvent dummyEvent(true, eQueryContentState, widget);
dummyEvent.Init(options);
InitEvent(dummyEvent, &pt);
nsIFrame* popupFrame = nsLayoutUtils::GetPopupFrameForEventCoordinates(
presContext->GetRootPresContext(), &dummyEvent);
nsIFrame* popupFrame = nsLayoutUtils::GetPopupFrameForPoint(
presContext->GetRootPresContext(), widget, pt);
LayoutDeviceIntRect widgetBounds = widget->GetClientBounds();
widgetBounds.MoveTo(0, 0);

View File

@ -1620,18 +1620,26 @@ nsPoint nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(Event* aDOMEvent,
return GetEventCoordinatesRelativeTo(event, RelativeTo{aFrame});
}
static bool IsValidCoordinateTypeEvent(const WidgetEvent* aEvent) {
if (!aEvent) {
return false;
}
return aEvent->mClass == eMouseEventClass ||
aEvent->mClass == eMouseScrollEventClass ||
aEvent->mClass == eWheelEventClass ||
aEvent->mClass == eDragEventClass ||
aEvent->mClass == eSimpleGestureEventClass ||
aEvent->mClass == ePointerEventClass ||
aEvent->mClass == eGestureNotifyEventClass ||
aEvent->mClass == eTouchEventClass ||
aEvent->mClass == eQueryContentEventClass;
}
nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
RelativeTo aFrame) {
if (!aEvent || (aEvent->mClass != eMouseEventClass &&
aEvent->mClass != eMouseScrollEventClass &&
aEvent->mClass != eWheelEventClass &&
aEvent->mClass != eDragEventClass &&
aEvent->mClass != eSimpleGestureEventClass &&
aEvent->mClass != ePointerEventClass &&
aEvent->mClass != eGestureNotifyEventClass &&
aEvent->mClass != eTouchEventClass &&
aEvent->mClass != eQueryContentEventClass))
if (!IsValidCoordinateTypeEvent(aEvent)) {
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
return GetEventCoordinatesRelativeTo(aEvent, aEvent->AsGUIEvent()->mRefPoint,
aFrame);
@ -1733,20 +1741,30 @@ nsPoint nsLayoutUtils::GetEventCoordinatesRelativeTo(
}
nsIFrame* nsLayoutUtils::GetPopupFrameForEventCoordinates(
nsPresContext* aPresContext, const WidgetEvent* aEvent) {
nsPresContext* aRootPresContext, const WidgetEvent* aEvent) {
if (!IsValidCoordinateTypeEvent(aEvent)) {
return nullptr;
}
const auto* guiEvent = aEvent->AsGUIEvent();
return GetPopupFrameForPoint(aRootPresContext, guiEvent->mWidget,
guiEvent->mRefPoint);
}
nsIFrame* nsLayoutUtils::GetPopupFrameForPoint(
nsPresContext* aRootPresContext, nsIWidget* aWidget,
const mozilla::LayoutDeviceIntPoint& aPoint) {
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (!pm) {
return nullptr;
}
nsTArray<nsIFrame*> popups;
pm->GetVisiblePopups(popups);
uint32_t i;
// Search from top to bottom
for (i = 0; i < popups.Length(); i++) {
nsIFrame* popup = popups[i];
if (popup->PresContext()->GetRootPresContext() == aPresContext &&
popup->ScrollableOverflowRect().Contains(
GetEventCoordinatesRelativeTo(aEvent, RelativeTo{popup}))) {
for (nsIFrame* popup : popups) {
if (popup->PresContext()->GetRootPresContext() == aRootPresContext &&
popup->ScrollableOverflowRect().Contains(GetEventCoordinatesRelativeTo(
aWidget, aPoint, RelativeTo{popup}))) {
return popup;
}
}

View File

@ -732,13 +732,26 @@ class nsLayoutUtils {
/**
* Get the popup frame of a given native mouse event.
* @param aPresContext only check popups within aPresContext or a descendant
* @param aRootPresContext only check popups within aRootPresContext or a
* descendant
* @param aEvent the event.
* @return Null, if there is no popup frame at the point, otherwise,
* returns top-most popup frame at the point.
*/
static nsIFrame* GetPopupFrameForEventCoordinates(
nsPresContext* aPresContext, const mozilla::WidgetEvent* aEvent);
nsPresContext* aRootPresContext, const mozilla::WidgetEvent* aEvent);
/**
* Get the popup frame of a given point relative to a widget.
* @param aRootPresContext only check popups within aRootPresContext or a
* descendant
* @param aEvent the event.
* @return Null, if there is no popup frame at the point, otherwise,
* returns top-most popup frame at the point.
*/
static nsIFrame* GetPopupFrameForPoint(
nsPresContext* aRootPresContext, nsIWidget* aWidget,
const mozilla::LayoutDeviceIntPoint& aPoint);
/**
* Get container and offset if aEvent collapses Selection.