diff options
author | Tor Lillqvist <tml@iki.fi> | 2012-09-26 13:42:54 +0300 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@suse.com> | 2012-09-26 13:50:29 +0300 |
commit | 5f373a002df2f083109bb7b2e0987258b6e2f9c4 (patch) | |
tree | c1c18959af97b6018382d5d807ab2c5d5b04d121 | |
parent | 85b660a618780479a466e65a83ab844358631fa4 (diff) |
Fix crash on Mac when a11y in use, and avoid infinite loop, fdo#47275
The code used static_cast blindly even if the object not necessarily
was of the assumed subclass. Crash followed. Use dynamic_cast instead
to be able to check, like the corresponding code for GTK a11y. After
that fix we then got a nice infinite loop whn an object apparently is
its own parent. Detect that and break out.
Whether accessibility for the affected parts of the GUI actually works
now for its real use cases, no idea. But anything is better than a
crash...
Change-Id: I862234e168db0bd19d185b0f1f73b733b570cac4
-rw-r--r-- | vcl/aqua/source/a11y/aqua11yfocustracker.cxx | 15 | ||||
-rw-r--r-- | vcl/aqua/source/a11y/aqua11ywrapper.mm | 7 |
2 files changed, 20 insertions, 2 deletions
diff --git a/vcl/aqua/source/a11y/aqua11yfocustracker.cxx b/vcl/aqua/source/a11y/aqua11yfocustracker.cxx index 65eaef132edc..b38af805630c 100644 --- a/vcl/aqua/source/a11y/aqua11yfocustracker.cxx +++ b/vcl/aqua/source/a11y/aqua11yfocustracker.cxx @@ -72,7 +72,20 @@ long AquaA11yFocusTracker::WindowEventHandler(AquaA11yFocusTracker *pFocusTracke pFocusTracker->tabpage_activated( getWindow(pEvent) ); break; case VCLEVENT_MENU_HIGHLIGHT: - pFocusTracker->menu_highlighted( static_cast < const VclMenuEvent * > (pEvent) ); + // Inspired by code in WindowEventHandler in + // vcl/unx/gtk/a11y/atkutil.cxx, find out what kind of event + // it is to avoid blindly using a static_cast and crash, + // fdo#47275. + if( const VclMenuEvent* pMenuEvent = dynamic_cast < const VclMenuEvent* > (pEvent) ) + { + pFocusTracker->menu_highlighted( pMenuEvent ); + } + else if( const VclAccessibleEvent* pAccEvent = dynamic_cast < const VclAccessibleEvent* > (pEvent) ) + { + Reference< XAccessible > xAccessible = pAccEvent->GetAccessible(); + if( xAccessible.is() ) + pFocusTracker->setFocusedObject( xAccessible ); + } break; default: break; diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm b/vcl/aqua/source/a11y/aqua11ywrapper.mm index a7bad3cc9a55..8acb5f41a73e 100644 --- a/vcl/aqua/source/a11y/aqua11ywrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm @@ -370,7 +370,12 @@ static BOOL isPopupMenuOpen = NO; // go upstairs until reaching the broken connection AquaA11yWrapper * aWrapper = self; while ( [ aWrapper accessibleContext ] -> getAccessibleParent().is() ) { - aWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ aWrapper accessibleContext ] -> getAccessibleParent() -> getAccessibleContext() ]; + AquaA11yWrapper *aTentativeParentWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ aWrapper accessibleContext ] -> getAccessibleParent() -> getAccessibleContext() ]; + // Quick-and-dirty fix for infinite loop after fixing crash in + // fdo#47275 + if ( aTentativeParentWrapper == aWrapper ) + break; + aWrapper = aTentativeParentWrapper; [ aWrapper autorelease ]; } // get associated NSWindow |