summaryrefslogtreecommitdiff
path: root/winaccessibility/source/service/AccObjectWinManager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'winaccessibility/source/service/AccObjectWinManager.cxx')
-rw-r--r--winaccessibility/source/service/AccObjectWinManager.cxx167
1 files changed, 100 insertions, 67 deletions
diff --git a/winaccessibility/source/service/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx
index b0ee01525de9..c8e5c7ac936b 100644
--- a/winaccessibility/source/service/AccObjectWinManager.cxx
+++ b/winaccessibility/source/service/AccObjectWinManager.cxx
@@ -73,8 +73,12 @@ AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
*/
AccObjectWinManager::~AccObjectWinManager()
{
- XIdAccList.clear();
- HwndXAcc.clear();
+ {
+ std::scoped_lock l(m_Mutex);
+
+ XIdAccList.clear();
+ HwndXAcc.clear();
+ }
XResIdAccList.clear();
XHWNDDocList.clear();
}
@@ -94,13 +98,7 @@ AccObjectWinManager::Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam)
if(lParam == OBJID_CLIENT )
{
- AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
- if(topWindowAccObj)
- {
- pRetIMAcc = topWindowAccObj->GetIMAccessible();
- if(pRetIMAcc)
- pRetIMAcc->AddRef();//increase COM reference count
- }
+ pRetIMAcc = GetTopWindowIMAccessible(hWnd);
}
if ( pRetIMAcc && lParam == OBJID_CLIENT )
@@ -122,6 +120,8 @@ AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
if( pXAcc == nullptr)
return nullptr;
+ std::scoped_lock l(m_Mutex);
+
XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc );
if ( pIndTemp == XIdAccList.end() )
return nullptr;
@@ -134,13 +134,26 @@ AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
* @param hWnd, top window handle
* @return pointer to AccObject
*/
-AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
+IMAccessible * AccObjectWinManager::GetTopWindowIMAccessible(HWND hWnd)
{
+ std::scoped_lock l(m_Mutex); // tdf#155794 for HwndXAcc and XIdAccList
+
XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
if(iterResult == HwndXAcc.end())
return nullptr;
XAccessible* pXAcc = iterResult->second;
- return GetAccObjByXAcc(pXAcc);
+ AccObject *const pAccObject(GetAccObjByXAcc(pXAcc));
+ if (!pAccObject)
+ {
+ return nullptr;
+ }
+ IMAccessible *const pRet(pAccObject->GetIMAccessible());
+ if (!pRet)
+ {
+ return nullptr;
+ }
+ pRet->AddRef();
+ return pRet;
}
/**
@@ -391,6 +404,8 @@ void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj )
*/
void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible const * pXAcc )
{
+ std::scoped_lock l(m_Mutex);
+
auto iter = std::find_if(HwndXAcc.begin(), HwndXAcc.end(),
[&pXAcc](XHWNDToXAccHash::value_type& rEntry) { return rEntry.second == pXAcc; });
if (iter != HwndXAcc.end())
@@ -433,35 +448,47 @@ void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
{
if( pXAcc == nullptr )
return;
- XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
- if( temp != XIdAccList.end() )
- {
- ResIdGen.SetSub( temp->second.GetResID() );
- }
- else
- {
- return;
- }
- AccObject& accObj = temp->second;
- DeleteAccChildNode( &accObj );
- DeleteAccListener( &accObj );
- if( accObj.GetIMAccessible() )
+ rtl::Reference<AccEventListener> pListener;
+
{
- accObj.GetIMAccessible()->Release();
+ std::scoped_lock l(m_Mutex);
+
+ XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
+ if( temp != XIdAccList.end() )
+ {
+ ResIdGen.SetSub( temp->second.GetResID() );
+ }
+ else
+ {
+ return;
+ }
+
+ AccObject& accObj = temp->second;
+ DeleteAccChildNode( &accObj );
+ pListener = DeleteAccListener(&accObj);
+ accObj.NotifyDestroy();
+ if( accObj.GetIMAccessible() )
+ {
+ accObj.GetIMAccessible()->Release();
+ }
+ size_t i = XResIdAccList.erase(accObj.GetResID());
+ assert(i != 0);
+ (void) i;
+ DeleteFromHwndXAcc(pXAcc);
+ if (accObj.GetRole() == AccessibleRole::DOCUMENT ||
+ accObj.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION ||
+ accObj.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET ||
+ accObj.GetRole() == AccessibleRole::DOCUMENT_TEXT)
+ {
+ XHWNDDocList.erase(accObj.GetParentHWND());
+ }
+ XIdAccList.erase(pXAcc); // note: this invalidates accObj so do it last!
}
- size_t i = XResIdAccList.erase(accObj.GetResID());
- assert(i != 0);
- (void) i;
- DeleteFromHwndXAcc(pXAcc);
- if (accObj.GetRole() == AccessibleRole::DOCUMENT ||
- accObj.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION ||
- accObj.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET ||
- accObj.GetRole() == AccessibleRole::DOCUMENT_TEXT)
+ if (pListener)
{
- XHWNDDocList.erase(accObj.GetParentHWND());
+ pListener->RemoveMeFromBroadcaster(false);
}
- XIdAccList.erase(pXAcc); // note: this invalidates accObj so do it last!
}
/**
@@ -469,13 +496,9 @@ void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
* @param pAccObj Accobject pointer.
* @return
*/
-void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
+rtl::Reference<AccEventListener> AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
{
- AccEventListener* listener = pAccObj->getListener();
- if( listener==nullptr )
- return;
- listener->RemoveMeFromBroadcaster();
- pAccObj->SetListener(nullptr);
+ return pAccObj->SetListener(nullptr);
}
/**
@@ -568,29 +591,6 @@ void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pPa
*/
bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
{
- XIdToAccObjHash::iterator itXacc = XIdAccList.find( pXAcc );
- if (itXacc != XIdAccList.end() )
- {
- short nCurRole =GetRole(pXAcc);
- if (AccessibleRole::SHAPE == nCurRole)
- {
- AccObject &objXacc = itXacc->second;
- AccObject *pObjParent = objXacc.GetParentObj();
- if (pObjParent &&
- pObjParent->GetXAccessible().is() &&
- pObjParent->GetXAccessible().get() != pParentXAcc)
- {
- XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( pParentXAcc );
- if(itXaccParent != XIdAccList.end())
- {
- objXacc.SetParentObj(&(itXaccParent->second));
- }
- }
- }
- return false;
- }
-
-
Reference< XAccessibleContext > pRContext;
if( pXAcc == nullptr)
@@ -600,6 +600,33 @@ bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentX
if( !pRContext.is() )
return false;
+ {
+ short nCurRole = GetRole(pXAcc);
+
+ std::scoped_lock l(m_Mutex);
+
+ XIdToAccObjHash::iterator itXacc = XIdAccList.find( pXAcc );
+ if (itXacc != XIdAccList.end() )
+ {
+ if (AccessibleRole::SHAPE == nCurRole)
+ {
+ AccObject &objXacc = itXacc->second;
+ AccObject *pObjParent = objXacc.GetParentObj();
+ if (pObjParent &&
+ pObjParent->GetXAccessible().is() &&
+ pObjParent->GetXAccessible().get() != pParentXAcc)
+ {
+ XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( pParentXAcc );
+ if(itXaccParent != XIdAccList.end())
+ {
+ objXacc.SetParentObj(&(itXaccParent->second));
+ }
+ }
+ }
+ return false;
+ }
+ }
+
if( pWnd == nullptr )
{
if(pParentXAcc)
@@ -647,9 +674,13 @@ bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentX
else
return false;
- XIdAccList.emplace(pXAcc, pObj);
- XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc );
- XResIdAccList.emplace(pObj.GetResID(),&(pIndTemp->second));
+ {
+ std::scoped_lock l(m_Mutex);
+
+ XIdAccList.emplace(pXAcc, pObj);
+ XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc );
+ XResIdAccList.emplace(pObj.GetResID(),&(pIndTemp->second));
+ }
AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
if( pCurObj )
@@ -673,6 +704,8 @@ bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentX
*/
void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible* pXAcc)
{
+ std::scoped_lock l(m_Mutex);
+
HwndXAcc.emplace(hWnd,pXAcc);
}