mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 455442 - improve hitTest, r=aaronlev, hwaara
This commit is contained in:
parent
0043dd1e1e
commit
bdd4fa5270
@ -58,7 +58,7 @@ interface nsIAccessibleRelation;
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(004b6882-2df1-49df-bb5f-0fb81a5b1edf)]
|
||||
[scriptable, uuid(c7520419-87ec-42bc-98cc-04c0bf173530)]
|
||||
interface nsIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -199,9 +199,25 @@ interface nsIAccessible : nsISupports
|
||||
* current accessible will be returned.
|
||||
* If the point is in neither the current accessible or a child, then
|
||||
* null will be returned.
|
||||
*
|
||||
* @param x screen's x coordinate
|
||||
* @param y screen's y coordinate
|
||||
* @return the deepest accessible child containing the given point
|
||||
*/
|
||||
nsIAccessible getChildAtPoint(in long x, in long y);
|
||||
|
||||
/**
|
||||
* Deepest accessible child which contains the coordinate at (x, y) in screen
|
||||
* pixels. If the point is in the current accessible but not in a child, the
|
||||
* current accessible will be returned. If the point is in neither the current
|
||||
* accessible or a child, then null will be returned.
|
||||
*
|
||||
* @param x screen's x coordinate
|
||||
* @param y screen's y coordinate
|
||||
* @return the deepest accessible child containing the given point
|
||||
*/
|
||||
nsIAccessible getDeepestChildAtPoint(in long x, in long y);
|
||||
|
||||
/**
|
||||
* Nth accessible child using zero-based index or last child if index less than zero
|
||||
*/
|
||||
|
@ -1104,10 +1104,10 @@ NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIAccessible getChildAtPoint (in long x, in long y); */
|
||||
// nsIAccessible getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
@ -1205,29 +1205,52 @@ nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
// Fall through -- the point is in this accessible but not in a child
|
||||
// We are allowed to return |this| as the answer
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
while (PR_TRUE) {
|
||||
accessible->GetParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
// Reached the top of the hierarchy
|
||||
// these bounds were inside an accessible that is not a descendant of this one
|
||||
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
|
||||
return NS_OK;
|
||||
}
|
||||
if (parent == this) {
|
||||
// We reached |this|, so |accessible| is the
|
||||
// child we want to return
|
||||
break;
|
||||
}
|
||||
accessible.swap(parent);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aAccessible = accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessible getChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
nsresult rv = GetDeepestChildAtPoint(aX, aY, aAccessible);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!*aAccessible)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAccessible> parent, accessible(*aAccessible);
|
||||
while (PR_TRUE) {
|
||||
accessible->GetParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
NS_ASSERTION(PR_FALSE,
|
||||
"Obtained accessible isn't a child of this accessible.");
|
||||
// Reached the top of the hierarchy. These bounds were inside an
|
||||
// accessible that is not a descendant of this one.
|
||||
|
||||
// If we can't find the point in a child, we will return the fallback
|
||||
// answer: we return |this| if the point is within it, otherwise nsnull.
|
||||
PRInt32 x, y, width, height;
|
||||
GetBounds(&x, &y, &width, &height);
|
||||
if (aX >= x && aX < x + width && aY >= y && aY < y + height)
|
||||
NS_ADDREF(*aAccessible = this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (parent == this) {
|
||||
// We reached |this|, so |accessible| is the child we want to return.
|
||||
NS_ADDREF(*aAccessible = accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
accessible.swap(parent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame)
|
||||
{
|
||||
/*
|
||||
|
@ -67,6 +67,7 @@ nsOuterDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessible::getChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
@ -85,6 +86,23 @@ nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return GetFirstChild(aAccessible); // Always return the inner doc unless bounds outside of it
|
||||
}
|
||||
|
||||
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsOuterDocAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
// Call getDeepestChildAtPoint on the fist child accessible of the outer
|
||||
// document accessible if the given point is inside of outer document.
|
||||
nsCOMPtr<nsIAccessible> childAcc;
|
||||
nsresult rv = GetChildAtPoint(aX, aY, getter_AddRefs(childAcc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!childAcc)
|
||||
return NS_OK;
|
||||
|
||||
return childAcc->GetDeepestChildAtPoint(aX, aY, aAccessible);
|
||||
}
|
||||
|
||||
void nsOuterDocAccessible::CacheChildren()
|
||||
{
|
||||
// An outer doc accessible usually has 1 nsDocAccessible child,
|
||||
|
@ -54,8 +54,12 @@ class nsOuterDocAccessible : public nsAccessibleWrap
|
||||
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
void CacheChildren();
|
||||
nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
|
@ -293,22 +293,17 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||
{
|
||||
if (mIsExpired)
|
||||
return nil;
|
||||
|
||||
|
||||
// Convert from cocoa's coordinate system to gecko's. According to the docs
|
||||
// the point we're given is guaranteed to be bottom-left screen coordinates.
|
||||
nsPoint geckoPoint;
|
||||
ConvertCocoaToGeckoPoint (point, geckoPoint);
|
||||
|
||||
// start iterating as deep down as we can on this point, with the current accessible as the root.
|
||||
// as soon as GetChildAtPoint() returns null, or can't descend further (without getting the same accessible again)
|
||||
// we stop.
|
||||
nsCOMPtr<nsIAccessible> deepestFoundChild, newChild(mGeckoAccessible);
|
||||
do {
|
||||
deepestFoundChild = newChild;
|
||||
deepestFoundChild->GetChildAtPoint((PRInt32)geckoPoint.x, (PRInt32)geckoPoint.y, getter_AddRefs(newChild));
|
||||
} while (newChild && newChild.get() != deepestFoundChild.get());
|
||||
nsCOMPtr<nsIAccessible> deepestFoundChild;
|
||||
mGeckoAccessible->GetDeepestChildAtPoint((PRInt32)geckoPoint.x,
|
||||
(PRInt32)geckoPoint.y,
|
||||
getter_AddRefs(deepestFoundChild));
|
||||
|
||||
|
||||
// if we found something, return its native accessible.
|
||||
if (deepestFoundChild) {
|
||||
mozAccessible *nativeChild = GetNativeFromGeckoAccessible(deepestFoundChild);
|
||||
|
@ -355,6 +355,15 @@ nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return GetCachedTreeitemAccessible(row, column, aAccessible);
|
||||
}
|
||||
|
||||
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
// Call getChildAtPoint until tree doesn't support complex content.
|
||||
return GetChildAtPoint(aX, aY, aAccessible);
|
||||
}
|
||||
|
||||
// Ask treeselection to get all selected children
|
||||
NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
|
||||
{
|
||||
|
@ -71,8 +71,11 @@ public:
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
|
||||
static nsresult GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32 *aCount);
|
||||
|
Loading…
Reference in New Issue
Block a user