diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2016-01-04 21:28:59 +0000 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2016-01-07 14:42:46 +0000 |
commit | 9a22f9f5fe528c7c0f45813a025b377f79c8372e (patch) | |
tree | bd498d62c2b9ea0764a543abc28df7f7e3e86c38 | |
parent | d48370043b3759c79340c162048c5f2b4da394b9 (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.
Reviewed-on: https://gerrit.libreoffice.org/21088
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Conflicts:
include/toolkit/awt/vclxaccessiblecomponent.hxx
toolkit/source/awt/vclxaccessiblecomponent.cxx
Change-Id: I56dfb76501929886f70495804670f8c4f70e796b
Reviewed-on: https://gerrit.libreoffice.org/21110
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r-- | include/toolkit/awt/vclxaccessiblecomponent.hxx | 15 | ||||
-rw-r--r-- | toolkit/source/awt/vclxaccessiblecomponent.cxx | 70 |
2 files changed, 43 insertions, 42 deletions
diff --git a/include/toolkit/awt/vclxaccessiblecomponent.hxx b/include/toolkit/awt/vclxaccessiblecomponent.hxx index 0fdc2a8f083f..f01183fa3d9b 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: - ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> mxWindow; - VCLXWindow* mpVCLXindow; + rtl::Reference<VCLXWindow> m_xVCLXWindow; + VclPtr<vcl::Window> m_xEventSource; VCLExternalSolarLock* m_pSolarLock; -protected: - DECL_LINK( WindowEventListener, VclSimpleEvent* ); - DECL_LINK( WindowChildEventListener, VclSimpleEvent* ); + DECL_LINK( WindowEventListener, VclSimpleEvent* ); + DECL_LINK( WindowChildEventListener, VclSimpleEvent* ); + 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 ::com::sun::star::uno::Reference< ::com::sun::star::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 9031492fbf2a..2d50fd528643 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 = NULL; @@ -104,13 +114,11 @@ uno::Sequence< OUString > VCLXAccessibleComponent::getSupportedServiceNames() th IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent ) { - DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); - - /* 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 ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #122218# */ && (pEvent->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 ( pEvent && pEvent->ISA( VclWindowEvent ) && m_xVCLXWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) ) { DBG_ASSERT( static_cast<VclWindowEvent*>(pEvent)->GetWindow(), "Window???" ); if( !static_cast<VclWindowEvent*>(pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) ) @@ -123,8 +131,7 @@ IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclSimpleEvent*, pEvent ) { - DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); - if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #i68079# */ ) + if ( pEvent && pEvent->ISA( VclWindowEvent ) && m_xVCLXWindow.is() /* #i68079# */ ) { DBG_ASSERT( static_cast<VclWindowEvent*>(pEvent)->GetWindow(), "Window???" ); if( !static_cast<VclWindowEvent*>(pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() ) @@ -192,10 +199,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 = NULL; + DisconnectEvents(); + m_xVCLXWindow.clear(); } break; case VCLEVENT_WINDOW_CHILDDESTROYED: @@ -344,16 +349,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 = NULL; + m_xVCLXWindow.clear(); } VclPtr<vcl::Window> VCLXAccessibleComponent::GetWindow() const @@ -770,8 +770,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) |