summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2016-05-13 15:46:10 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-05-17 07:19:13 +0000
commitdc5ab01a75877d4f4c79b7ff734d3f41a232c31f (patch)
tree71792678d6bd58fd7302941ef3ad9db60866c004
parentd4e284ab44f4644a60eea50052f7940098541145 (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 (cherry picked from commit 6afa142fdecc3a7f2f182bcd2c035bf3089f1ce8) Reviewed-on: https://gerrit.libreoffice.org/24979 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r--sw/source/core/access/accframe.hxx3
-rw-r--r--sw/source/core/access/accmap.cxx15
2 files changed, 13 insertions, 5 deletions
diff --git a/sw/source/core/access/accframe.hxx b/sw/source/core/access/accframe.hxx
index 55d9e2497043..7685c590e06d 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 8f6c9da395bf..ed9ec9db9b29 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
{