diff options
author | Michael Stahl <mstahl@redhat.com> | 2016-05-13 15:46:10 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2016-05-13 16:14:41 +0200 |
commit | 6afa142fdecc3a7f2f182bcd2c035bf3089f1ce8 (patch) | |
tree | e9caafec522ac55e11ae36a308e8298f9c4456ed /sw | |
parent | b35b601d9e3b43eaedb8576b70d10b657f625d6e (diff) |
tdf#99722 sw: avoid buffering a11y events for not-visible frames
The problem with the bugdoc is that all pages are moved by 60 twips or
so in CheckViewLayout(), which generates a event for every SwTextFrame
but there is no SwAccessible for the SwTextFrame yet hence it is a
CHILD_POS_CHANGE on the parent, which happens to be (because SwPageFrames
are not accessible) the SwRootFrame so that's how we get an enormous number
(~90k per 500 pages) WeakReference in the buffered
SwAccessibleEvent_Impl pointing to the same object (the SwAccessible of
the root frame).
Then at a later stage the events are actually sent and
SwAccessibleContext::InvalidateChildPosOrSize() discards all but 80 or
so that are on the first page.
So check the visiblility before buffering the event, to avoid
scalability issues in the WeakReference.
This brings the cpu-time from 1:37 to 0:17 for the 500 pager, and the
full bugdoc is now just 3-4 seconds slower than with a11y disabled.
Change-Id: Ia91653fd7572f32ce3cf765a4ecd2b7077ace8f6
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/access/accframe.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/access/accmap.cxx | 15 |
2 files changed, 13 insertions, 5 deletions
diff --git a/sw/source/core/access/accframe.hxx b/sw/source/core/access/accframe.hxx index f128bee19276..337ecb310ada 100644 --- a/sw/source/core/access/accframe.hxx +++ b/sw/source/core/access/accframe.hxx @@ -76,16 +76,17 @@ protected: ::std::list< sw::access::SwAccessibleChild >& rChildren, bool bInPagePreview ); -protected: bool IsEditable( SwViewShell *pVSh ) const; bool IsOpaque( SwViewShell *pVSh ) const; +public: bool IsShowing( const SwAccessibleMap& rAccMap, const sw::access::SwAccessibleChild& rFrameOrObj ) const; inline bool IsShowing( const SwRect& rFrame ) const; inline bool IsShowing( const SwAccessibleMap& rAccMap ) const; +protected: inline bool IsInPagePreview() const { return mbIsInPagePreview; diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 1f0fec976995..24dae46d111c 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -2437,10 +2437,17 @@ void SwAccessibleMap::InvalidatePosOrSize( const SwFrame *pFrame, { if( GetShell()->ActionPend() ) { - SwAccessibleEvent_Impl aEvent( - SwAccessibleEvent_Impl::CHILD_POS_CHANGED, - xParentAccImpl.get(), aFrameOrObj, rOldBox ); - AppendEvent( aEvent ); + assert(pParent); + // tdf#99722 faster not to buffer events that won't be sent + if (!SwAccessibleChild(pParent).IsVisibleChildrenOnly() + || xParentAccImpl->IsShowing(rOldBox) + || xParentAccImpl->IsShowing(*this, aFrameOrObj)) + { + SwAccessibleEvent_Impl aEvent( + SwAccessibleEvent_Impl::CHILD_POS_CHANGED, + xParentAccImpl.get(), aFrameOrObj, rOldBox ); + AppendEvent( aEvent ); + } } else { |