Kaydet (Commit) 7576f273 authored tarafından Michael Meeks's avatar Michael Meeks

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/21088Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst bca7a335
...@@ -63,15 +63,16 @@ class TOOLKIT_DLLPUBLIC VCLXAccessibleComponent ...@@ -63,15 +63,16 @@ class TOOLKIT_DLLPUBLIC VCLXAccessibleComponent
,public VCLXAccessibleComponent_BASE ,public VCLXAccessibleComponent_BASE
{ {
private: private:
css::uno::Reference< css::awt::XWindow> mxWindow; rtl::Reference<VCLXWindow> m_xVCLXWindow;
VCLXWindow* mpVCLXindow; VclPtr<vcl::Window> m_xEventSource;
VCLExternalSolarLock* m_pSolarLock; VCLExternalSolarLock* m_pSolarLock;
protected:
DECL_LINK_TYPED( WindowEventListener, VclWindowEvent&, void ); DECL_LINK_TYPED( WindowEventListener, VclWindowEvent&, void );
DECL_LINK_TYPED( WindowChildEventListener, VclWindowEvent&, void ); DECL_LINK_TYPED( WindowChildEventListener, VclWindowEvent&, void );
void DisconnectEvents();
protected:
virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ); virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent );
virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet ); virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet );
...@@ -80,10 +81,10 @@ protected: ...@@ -80,10 +81,10 @@ protected:
virtual css::uno::Reference< css::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent ); virtual css::uno::Reference< css::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent );
public: public:
VCLXAccessibleComponent( VCLXWindow* pVCLXindow ); VCLXAccessibleComponent( VCLXWindow* pVCLXWindow );
virtual ~VCLXAccessibleComponent(); virtual ~VCLXAccessibleComponent();
VCLXWindow* GetVCLXWindow() const { return mpVCLXindow; } VCLXWindow* GetVCLXWindow() const;
VclPtr<vcl::Window> GetWindow() const; VclPtr<vcl::Window> GetWindow() const;
template< class derived_type > VclPtr< derived_type > GetAs() const { template< class derived_type > VclPtr< derived_type > GetAs() const {
return VclPtr< derived_type >( static_cast< derived_type * >( GetWindow().get() ) ); } return VclPtr< derived_type >( static_cast< derived_type * >( GetWindow().get() ) ); }
......
...@@ -42,35 +42,45 @@ ...@@ -42,35 +42,45 @@
using namespace ::com::sun::star; using namespace ::com::sun::star;
using namespace ::comphelper; using namespace ::comphelper;
VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow ) VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXWindow )
: AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() ) : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
, OAccessibleImplementationAccess( ) , OAccessibleImplementationAccess( )
{ {
mpVCLXindow = pVCLXindow; m_xVCLXWindow = pVCLXWindow;
mxWindow = pVCLXindow;
m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) ); m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) );
DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" ); DBG_ASSERT( pVCLXWindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
if ( pVCLXindow->GetWindow() ) m_xEventSource = pVCLXWindow->GetWindow();
if ( m_xEventSource )
{ {
pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); m_xEventSource->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); m_xEventSource->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
} }
// announce the XAccessible of our creator to the base class // 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 ) ); m_xEventSource->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); m_xEventSource->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
m_xEventSource.clear();
} }
}
VCLXAccessibleComponent::~VCLXAccessibleComponent()
{
ensureDisposed();
DisconnectEvents();
delete m_pSolarLock; delete m_pSolarLock;
m_pSolarLock = nullptr; m_pSolarLock = nullptr;
...@@ -107,7 +117,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, ...@@ -107,7 +117,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&,
* might have been destroyed by the previous VCLEventListener (if no AT tool * might have been destroyed by the previous VCLEventListener (if no AT tool
* is running), e.g. sub-toolbars in impress. * is running), e.g. sub-toolbars in impress.
*/ */
if ( mxWindow.is() /* #122218# */ && (rEvent.GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) ) if ( m_xVCLXWindow.is() /* #122218# */ && (rEvent.GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
{ {
DBG_ASSERT( rEvent.GetWindow(), "Window???" ); DBG_ASSERT( rEvent.GetWindow(), "Window???" );
if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VCLEVENT_OBJECT_DYING ) ) if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VCLEVENT_OBJECT_DYING ) )
...@@ -119,7 +129,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, ...@@ -119,7 +129,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&,
IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowChildEventListener, VclWindowEvent&, rEvent, void ) IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowChildEventListener, VclWindowEvent&, rEvent, void )
{ {
if ( mxWindow.is() /* #i68079# */ ) if ( m_xVCLXWindow.is() /* #i68079# */ )
{ {
DBG_ASSERT( rEvent.GetWindow(), "Window???" ); DBG_ASSERT( rEvent.GetWindow(), "Window???" );
if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() ) if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() )
...@@ -186,10 +196,8 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind ...@@ -186,10 +196,8 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind
{ {
case VCLEVENT_OBJECT_DYING: case VCLEVENT_OBJECT_DYING:
{ {
pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) ); DisconnectEvents();
pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) ); m_xVCLXWindow.clear();
mxWindow.clear();
mpVCLXindow = nullptr;
} }
break; break;
case VCLEVENT_WINDOW_CHILDDESTROYED: case VCLEVENT_WINDOW_CHILDDESTROYED:
...@@ -338,16 +346,11 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind ...@@ -338,16 +346,11 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind
void VCLXAccessibleComponent::disposing() void VCLXAccessibleComponent::disposing()
{ {
if ( mpVCLXindow && mpVCLXindow->GetWindow() ) DisconnectEvents();
{
mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
}
AccessibleExtendedComponentHelper_BASE::disposing(); AccessibleExtendedComponentHelper_BASE::disposing();
mxWindow.clear(); m_xVCLXWindow.clear();
mpVCLXindow = nullptr;
} }
VclPtr<vcl::Window> VCLXAccessibleComponent::GetWindow() const VclPtr<vcl::Window> VCLXAccessibleComponent::GetWindow() const
...@@ -761,8 +764,8 @@ void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException, std::e ...@@ -761,8 +764,8 @@ void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException, std::e
OExternalLockGuard aGuard( this ); OExternalLockGuard aGuard( this );
uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet(); uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet();
if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) ) if ( m_xVCLXWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
mxWindow->setFocus(); m_xVCLXWindow->setFocus();
} }
sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException, std::exception) sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException, std::exception)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment