sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx |    2 +
 sc/source/ui/Accessibility/AccessibleTableBase.cxx   |   20 +++++++---
 vcl/aqua/source/a11y/aqua11ywrapper.mm               |   37 +++++++++++++------
 3 files changed, 44 insertions(+), 15 deletions(-)

New commits:
commit 15aac31ebac23ef745400a8d9c146aef85923c9d
Author: Michael Meeks <michael.me...@suse.com>
Date:   Tue Dec 18 13:29:03 2012 +0000

    fdo#56937 - mac a11y hang related to traversing vast, broken hierarchies.
    
    Change-Id: Iff0537a69b2c6ae929da6a05f26c0d55415d6d8a

diff --git a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx 
b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
index d57d92e..e4d0060 100644
--- a/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
+++ b/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx
@@ -44,6 +44,8 @@ using namespace ::com::sun::star::accessibility;
 
 //=====  internal  ============================================================
 
+// FIXME: really unclear why we have an ScAccessibleTableBase with
+// only this single sub-class
 ScAccessibleSpreadsheet::ScAccessibleSpreadsheet(
         ScAccessibleDocument* pAccDoc,
         ScTabViewShell* pViewShell,
diff --git a/sc/source/ui/Accessibility/AccessibleTableBase.cxx 
b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
index 780638b..3a950c4 100644
--- a/sc/source/ui/Accessibility/AccessibleTableBase.cxx
+++ b/sc/source/ui/Accessibility/AccessibleTableBase.cxx
@@ -261,7 +261,7 @@ sal_Bool SAL_CALL 
ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow
     return false;
 }
 
-    //=====  XAccessibleExtendedTable  ========================================
+// =====  XAccessibleExtendedTable  ========================================
 
 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, 
sal_Int32 nColumn )
     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
@@ -304,7 +304,7 @@ sal_Int32 SAL_CALL 
ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildI
     return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - 
maRange.aStart.Col() + 1);
 }
 
-    //=====  XAccessibleContext  ==============================================
+// =====  XAccessibleContext  ==============================================
 
 sal_Int32 SAL_CALL
     ScAccessibleTableBase::getAccessibleChildCount(void)
@@ -312,9 +312,16 @@ sal_Int32 SAL_CALL
 {
     SolarMutexGuard aGuard;
     IsObjectValid();
-    return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 
1) *
-            (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
-//  return 1;
+
+    // FIXME: representing rows & columns this way is a plain and simple 
madness.
+    // this needs a radical re-think.
+    sal_Int64 nMax = ((sal_Int64)(maRange.aEnd.Row() - maRange.aStart.Row() + 
1) *
+                      (sal_Int64)(maRange.aEnd.Col() - maRange.aStart.Col() + 
1));
+    if (nMax > SAL_MAX_INT32)
+        nMax = SAL_MAX_INT32;
+    if (nMax < 0)
+        return 0;
+    return static_cast<sal_Int32>(nMax);
 }
 
 uno::Reference< XAccessible > SAL_CALL
@@ -328,6 +335,9 @@ uno::Reference< XAccessible > SAL_CALL
     if (nIndex >= getAccessibleChildCount() || nIndex < 0)
         throw lang::IndexOutOfBoundsException();
 
+    // FIXME: representing rows & columns this way is a plain and simple 
madness.
+    // this needs a radical re-think.
+
     sal_Int32 nRow(0);
     sal_Int32 nColumn(0);
     sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm 
b/vcl/aqua/source/a11y/aqua11ywrapper.mm
index b3517b0..94dbe1b 100644
--- a/vcl/aqua/source/a11y/aqua11ywrapper.mm
+++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm
@@ -977,21 +977,38 @@ Reference < XAccessibleContext > hitTestRunner ( 
com::sun::star::awt::Point poin
         Reference < XAccessibleComponent > rxAccessibleComponent ( 
rxAccessibleContext, UNO_QUERY );
         if ( rxAccessibleComponent.is() ) {
             com::sun::star::awt::Point location = rxAccessibleComponent -> 
getLocationOnScreen();
-            com::sun::star::awt::Point hitPoint ( point.X - location.X , 
point.Y - location.Y); 
+            com::sun::star::awt::Point hitPoint ( point.X - location.X , 
point.Y - location.Y);
             Reference < XAccessible > rxAccessible = rxAccessibleComponent -> 
getAccessibleAtPoint ( hitPoint );
             if ( rxAccessible.is() && rxAccessible -> 
getAccessibleContext().is() &&
                  rxAccessible -> getAccessibleContext() -> 
getAccessibleChildCount() == 0 ) {
                 hitChild = rxAccessible -> getAccessibleContext();
             }
-        } 
-        if ( !hitChild.is() && rxAccessibleContext -> 
getAccessibleChildCount() > 0 ) { // special treatment for e.g. comboboxes
-            for ( int i = 0; i < rxAccessibleContext -> 
getAccessibleChildCount(); i++ ) {
-                Reference < XAccessible > rxAccessibleChild = 
rxAccessibleContext -> getAccessibleChild ( i );
-                if ( rxAccessibleChild.is() && rxAccessibleChild -> 
getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> 
getAccessibleRole() != AccessibleRole::LIST ) {
-                    Reference < XAccessibleContext > myHitChild = 
hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() );
-                    if ( myHitChild.is() ) {
-                        hitChild = myHitChild;
-                        break;
+        }
+
+        // iterate the hirerachy looking doing recursive hit testing.
+        // apparently necessary as a special treatment for e.g. comboboxes
+        if ( !hitChild.is() ) {
+            bool bSafeToIterate = true;
+            sal_Int32 nCount = rxAccessibleContext -> 
getAccessibleChildCount();
+
+            if ( nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for 
anyone */ )
+                bSafeToIterate = false;
+            else { // manages descendants is an horror from the a11y standards 
guys.
+                Reference< XAccessibleStateSet > xStateSet;
+                xStateSet = rxAccessibleContext -> getAccessibleStateSet();
+                if (xStateSet.is() && xStateSet -> 
contains(AccessibleStateType::MANAGES_DESCENDANTS ) )
+                    bSafeToIterate = false;
+            }
+
+            if( bSafeToIterate ) {
+                for ( int i = 0; i < rxAccessibleContext -> 
getAccessibleChildCount(); i++ ) {
+                    Reference < XAccessible > rxAccessibleChild = 
rxAccessibleContext -> getAccessibleChild ( i );
+                    if ( rxAccessibleChild.is() && rxAccessibleChild -> 
getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> 
getAccessibleRole() != AccessibleRole::LIST ) {
+                        Reference < XAccessibleContext > myHitChild = 
hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() );
+                        if ( myHitChild.is() ) {
+                            hitChild = myHitChild;
+                            break;
+                        }
                     }
                 }
             }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to