|
 |
f325b2 |
From 12776a97a32449f5c0fc6de735c29fc30c0d7d14 Mon Sep 17 00:00:00 2001
|
|
 |
f325b2 |
From: David Tardon <dtardon@redhat.com>
|
|
 |
f325b2 |
Date: Tue, 10 May 2016 09:00:20 +0200
|
|
 |
f325b2 |
Subject: [PATCH] improve perf. of VCL event dispatch
|
|
 |
f325b2 |
|
|
 |
f325b2 |
Change-Id: I5052f0c3e2c8739b336da52ef9590e5008255247
|
|
 |
f325b2 |
---
|
|
 |
f325b2 |
vcl/inc/window.h | 4 +++-
|
|
 |
f325b2 |
vcl/source/window/event.cxx | 39 ++++++++++++++++++++++++++++++++++++---
|
|
 |
f325b2 |
vcl/source/window/window.cxx | 1 +
|
|
 |
f325b2 |
3 files changed, 40 insertions(+), 4 deletions(-)
|
|
 |
f325b2 |
|
|
 |
f325b2 |
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
|
|
 |
f325b2 |
index 67d5f94..60f7e82 100644
|
|
 |
f325b2 |
--- a/vcl/inc/window.h
|
|
 |
f325b2 |
+++ b/vcl/inc/window.h
|
|
 |
f325b2 |
@@ -224,7 +224,9 @@ public:
|
|
 |
f325b2 |
VclPtr<vcl::Window> mpNextOverlap;
|
|
 |
f325b2 |
VclPtr<vcl::Window> mpLastFocusWindow;
|
|
 |
f325b2 |
VclPtr<vcl::Window> mpDlgCtrlDownWindow;
|
|
 |
f325b2 |
- VclEventListeners maEventListeners;
|
|
 |
f325b2 |
+ std::vector<Link<>> maEventListeners;
|
|
 |
f325b2 |
+ int mnEventListenersIteratingCount;
|
|
 |
f325b2 |
+ std::set<Link<>> maEventListenersDeleted;
|
|
 |
f325b2 |
VclEventListeners maChildEventListeners;
|
|
 |
f325b2 |
|
|
 |
f325b2 |
// The canvas interface for this VCL window. Is persistent after the first GetCanvas() call
|
|
 |
f325b2 |
diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx
|
|
 |
f325b2 |
index 35c3e38..cbd5b23 100644
|
|
 |
f325b2 |
--- a/vcl/source/window/event.cxx
|
|
 |
f325b2 |
+++ b/vcl/source/window/event.cxx
|
|
 |
f325b2 |
@@ -18,6 +18,7 @@
|
|
 |
f325b2 |
*/
|
|
 |
f325b2 |
|
|
 |
f325b2 |
#include <vcl/event.hxx>
|
|
 |
f325b2 |
+#include <vcl/vclevent.hxx>
|
|
 |
f325b2 |
#include <vcl/window.hxx>
|
|
 |
f325b2 |
#include <vcl/dockwin.hxx>
|
|
 |
f325b2 |
#include <vcl/layout.hxx>
|
|
 |
f325b2 |
@@ -27,6 +28,8 @@
|
|
 |
f325b2 |
#include <svdata.hxx>
|
|
 |
f325b2 |
#include <salframe.hxx>
|
|
 |
f325b2 |
|
|
 |
f325b2 |
+#include <comphelper/scopeguard.hxx>
|
|
 |
f325b2 |
+
|
|
 |
f325b2 |
#include <com/sun/star/awt/MouseEvent.hpp>
|
|
 |
f325b2 |
#include <com/sun/star/awt/KeyModifier.hpp>
|
|
 |
f325b2 |
#include <com/sun/star/awt/MouseButton.hpp>
|
|
 |
f325b2 |
@@ -212,7 +215,32 @@ void Window::CallEventListeners( sal_uLong nEvent, void* pData )
|
|
 |
f325b2 |
if ( aDelData.IsDead() )
|
|
 |
f325b2 |
return;
|
|
 |
f325b2 |
|
|
 |
f325b2 |
- mpWindowImpl->maEventListeners.Call( &aEvent );
|
|
 |
f325b2 |
+ if (!mpWindowImpl->maEventListeners.empty())
|
|
 |
f325b2 |
+ {
|
|
 |
f325b2 |
+ // Copy the list, because this can be destroyed when calling a Link...
|
|
 |
f325b2 |
+ std::vector<Link<>> aCopy( mpWindowImpl->maEventListeners );
|
|
 |
f325b2 |
+ // we use an iterating counter/flag and a set of deleted Link's to avoid O(n^2) behaviour
|
|
 |
f325b2 |
+ mpWindowImpl->mnEventListenersIteratingCount++;
|
|
 |
f325b2 |
+ auto& rWindowImpl = *mpWindowImpl;
|
|
 |
f325b2 |
+ comphelper::ScopeGuard aGuard(
|
|
 |
f325b2 |
+ [&rWindowImpl, &aDelData]()
|
|
 |
f325b2 |
+ {
|
|
 |
f325b2 |
+ if (!aDelData.IsDead())
|
|
 |
f325b2 |
+ {
|
|
 |
f325b2 |
+ rWindowImpl.mnEventListenersIteratingCount--;
|
|
 |
f325b2 |
+ if (rWindowImpl.mnEventListenersIteratingCount == 0)
|
|
 |
f325b2 |
+ rWindowImpl.maEventListenersDeleted.clear();
|
|
 |
f325b2 |
+ }
|
|
 |
f325b2 |
+ }
|
|
 |
f325b2 |
+ );
|
|
 |
f325b2 |
+ for ( Link<>& rLink : aCopy )
|
|
 |
f325b2 |
+ {
|
|
 |
f325b2 |
+ if (aDelData.IsDead()) break;
|
|
 |
f325b2 |
+ // check this hasn't been removed in some re-enterancy scenario fdo#47368
|
|
 |
f325b2 |
+ if( rWindowImpl.maEventListenersDeleted.find(rLink) == rWindowImpl.maEventListenersDeleted.end() )
|
|
 |
f325b2 |
+ rLink.Call( &aEvent );
|
|
 |
f325b2 |
+ }
|
|
 |
f325b2 |
+ }
|
|
 |
f325b2 |
|
|
 |
f325b2 |
if ( aDelData.IsDead() )
|
|
 |
f325b2 |
return;
|
|
 |
f325b2 |
@@ -245,13 +273,18 @@ void Window::FireVclEvent( VclSimpleEvent* pEvent )
|
|
 |
f325b2 |
|
|
 |
f325b2 |
void Window::AddEventListener( const Link<>& rEventListener )
|
|
 |
f325b2 |
{
|
|
 |
f325b2 |
- mpWindowImpl->maEventListeners.addListener( rEventListener );
|
|
 |
f325b2 |
+ mpWindowImpl->maEventListeners.push_back( rEventListener );
|
|
 |
f325b2 |
}
|
|
 |
f325b2 |
|
|
 |
f325b2 |
void Window::RemoveEventListener( const Link<>& rEventListener )
|
|
 |
f325b2 |
{
|
|
 |
f325b2 |
if (mpWindowImpl)
|
|
 |
f325b2 |
- mpWindowImpl->maEventListeners.removeListener( rEventListener );
|
|
 |
f325b2 |
+ {
|
|
 |
f325b2 |
+ auto& rListeners = mpWindowImpl->maEventListeners;
|
|
 |
f325b2 |
+ rListeners.erase( std::remove(rListeners.begin(), rListeners.end(), rEventListener ), rListeners.end() );
|
|
 |
f325b2 |
+ if (mpWindowImpl->mnEventListenersIteratingCount)
|
|
 |
f325b2 |
+ mpWindowImpl->maEventListenersDeleted.insert(rEventListener);
|
|
 |
f325b2 |
+ }
|
|
 |
f325b2 |
}
|
|
 |
f325b2 |
|
|
 |
f325b2 |
void Window::AddChildEventListener( const Link<>& rEventListener )
|
|
 |
f325b2 |
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
|
|
 |
f325b2 |
index e8d2b96..cbfc4cd 100644
|
|
 |
f325b2 |
--- a/vcl/source/window/window.cxx
|
|
 |
f325b2 |
+++ b/vcl/source/window/window.cxx
|
|
 |
f325b2 |
@@ -630,6 +630,7 @@ WindowImpl::WindowImpl( WindowType nType )
|
|
 |
f325b2 |
mpLastFocusWindow = NULL; // window for focus restore
|
|
 |
f325b2 |
mpDlgCtrlDownWindow = NULL; // window for dialog control
|
|
 |
f325b2 |
mpFirstDel = NULL; // Dtor notification list
|
|
 |
f325b2 |
+ mnEventListenersIteratingCount = 0;
|
|
 |
f325b2 |
mpUserData = NULL; // user data
|
|
 |
f325b2 |
mpCursor = NULL; // cursor
|
|
 |
f325b2 |
mpControlFont = NULL; // font properties
|
|
 |
f325b2 |
--
|
|
 |
f325b2 |
2.7.3
|
|
 |
f325b2 |
|