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
,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 );
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() ) ); }
......
......@@ -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;
......@@ -107,7 +117,7 @@ IMPL_LINK_TYPED( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&,
* 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) )
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)
......
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