diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2016-01-04 21:28:59 +0000 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-01-06 08:24:59 +0000 |
commit | 9288631d11987087da7b9997937ae4b7b556fabc (patch) | |
tree | 913a6d6fa7b1b9ad708644e542ceace20c475496 | |
parent | 451c814d518527e77725a7ac9a99cd22fa08914c (diff) |
tdf#94715 - ensure we remove ourselves from the same event source.
Seemingly event removal was not occuring; also clean up historic
duplication of UNO and C++ references using rtl::Reference.
Change-Id: I56dfb76501929886f70495804670f8c4f70e796b
Reviewed-on: https://gerrit.libreoffice.org/21088
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/21108
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r-- | include/toolkit/awt/vclxaccessiblecomponent.hxx | 15 | ||||
-rw-r--r-- | toolkit/source/awt/vclxaccessiblecomponent.cxx | 67 |
2 files changed, 43 insertions, 39 deletions
diff --git a/include/toolkit/awt/vclxaccessiblecomponent.hxx b/include/toolkit/awt/vclxaccessiblecomponent.hxx index b1fda894b29f..7025540894ba 100644 --- a/include/toolkit/awt/vclxaccessiblecomponent.hxx +++ b/include/toolkit/awt/vclxaccessiblecomponent.hxx @@ -63,15 +63,16 @@ class TOOLKIT_DLLPUBLIC VCLXAccessibleComponent ,public VCLXAccessibleComponent_BASE { private: - css::uno::Reference< css::awt::XWindow> mxWindow; - VCLXWindow* mpVCLXindow; + rtl::Reference<VCLXWindow> m_xVCLXWindow; + VclPtr<vcl::Window> m_xEventSource; VCLExternalSolarLock* m_pSolarLock; -protected: - DECL_LINK_TYPED( WindowEventListener, VclWindowEvent&, void ); - DECL_LINK_TYPED( WindowChildEventListener, VclWindowEvent&, void ); + DECL_LINK_TYPED( WindowEventListener, VclWindowEvent&, void ); + DECL_LINK_TYPED( WindowChildEventListener, VclWindowEvent&, void ); + void DisconnectEvents(); +protected: virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ); virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ); @@ -80,10 +81,10 @@ protected: virtual css::uno::Reference< css::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent ); public: - VCLXAccessibleComponent( VCLXWindow* pVCLXindow ); + VCLXAccessibleComponent( VCLXWindow* pVCLXWindow ); virtual ~VCLXAccessibleComponent(); - VCLXWindow* GetVCLXWindow() const { return mpVCLXindow; } + VCLXWindow* GetVCLXWindow() const; VclPtr<vcl::Window> GetWindow() const; template< class derived_type > VclPtr< derived_type > GetAs() const { return VclPtr< derived_type >( static_cast< derived_type * >( GetWindow().get() ) ); } diff --git a/toolkit/source/awt/vclxaccessiblecomponent.cxx b/toolkit/source/awt/vclxaccessiblecomponent.cxx index a037109f1f2f..bc9c5fa7713d 100644 --- a/toolkit/source/awt/vclxaccessiblecomponent.cxx +++ b/toolkit/source/awt/vclxaccessiblecomponent.cxx @@ -42,35 +42,45 @@ using namespace ::com::sun::star; using namespace ::comphelper; -VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow ) +VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXWindow ) : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() ) , OAccessibleImplementationAccess( ) { - mpVCLXindow = pVCLXindow; - mxWindow = pVCLXindow; + m_xVCLXWindow = pVCLXWindow; m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) ); - DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" ); - if ( pVCLXindow->GetWindow() ) + DBG_ASSERT( pVCLXWindow->GetWindow(), "VCLXAccessibleComponent - no window!" ); + m_xEventSource = pVCLXWindow->GetWindow(); + if ( m_xEventSource ) { - pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); - pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); + m_xEventSource->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); + m_xEventSource->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); } // announce the XAccessible of our creator to the base class - lateInit( pVCLXindow ); + lateInit( pVCLXWindow ); } -VCLXAccessibleComponent::~VCLXAccessibleComponent() +VCLXWindow* VCLXAccessibleComponent::GetVCLXWindow() const { - ensureDisposed(); + return m_xVCLXWindow.get(); +} - if ( mpVCLXindow && mpVCLXindow->GetWindow() ) +void VCLXAccessibleComponent::DisconnectEvents() +{ + if ( m_xEventSource ) { - mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); - mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); + m_xEventSource->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); + m_xEventSource->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); + m_xEventSource.clear(); } +} + +VCLXAccessibleComponent::~VCLXAccessibleComponent() +{ + ensureDisposed(); + DisconnectEvents(); delete m_pSolarLock; m_pSolarLock = nullptr; @@ -103,11 +113,11 @@ uno::Sequence< OUString > VCLXAccessibleComponent::getSupportedServiceNames() th IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, rEvent, void ) { - /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper - * might have been destroyed by the previous VCLEventListener (if no AT tool - * is running), e.g. sub-toolbars in impress. - */ - if ( mxWindow.is() /* #122218# */ && (rEvent.GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) ) + /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper + * might have been destroyed by the previous VCLEventListener (if no AT tool + * is running), e.g. sub-toolbars in impress. + */ + if ( m_xVCLXWindow.is() /* #122218# */ && (rEvent.GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) ) { DBG_ASSERT( rEvent.GetWindow(), "Window???" ); if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VCLEVENT_OBJECT_DYING ) ) @@ -119,7 +129,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowChildEventListener, VclWindowEvent&, rEvent, void ) { - if ( mxWindow.is() /* #i68079# */ ) + if ( m_xVCLXWindow.is() /* #i68079# */ ) { DBG_ASSERT( rEvent.GetWindow(), "Window???" ); if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() ) @@ -186,10 +196,8 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind { case VCLEVENT_OBJECT_DYING: { - pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); - pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); - mxWindow.clear(); - mpVCLXindow = nullptr; + DisconnectEvents(); + m_xVCLXWindow.clear(); } break; case VCLEVENT_WINDOW_CHILDDESTROYED: @@ -338,16 +346,11 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind void VCLXAccessibleComponent::disposing() { - if ( mpVCLXindow && mpVCLXindow->GetWindow() ) - { - mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); - mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); - } + DisconnectEvents(); AccessibleExtendedComponentHelper_BASE::disposing(); - mxWindow.clear(); - mpVCLXindow = nullptr; + m_xVCLXWindow.clear(); } VclPtr<vcl::Window> VCLXAccessibleComponent::GetWindow() const @@ -761,8 +764,8 @@ void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException, std::e OExternalLockGuard aGuard( this ); uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet(); - if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) ) - mxWindow->setFocus(); + if ( m_xVCLXWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) ) + m_xVCLXWindow->setFocus(); } sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException, std::exception) |