[Libreoffice-commits] .: Branch 'libreoffice-4-0' - sc/source vcl/aqua

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Dec 18 08:45:42 PST 2012


 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 a4a467c6e742ea40986287c5f546b0daec295289
Author: Michael Meeks <michael.meeks at 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;
+                        }
                     }
                 }
             }


More information about the Libreoffice-commits mailing list