summaryrefslogtreecommitdiff
path: root/toolkit
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2005-07-08 09:27:53 +0000
committerOliver Bolte <obo@openoffice.org>2005-07-08 09:27:53 +0000
commit08e4815d00bffdc53295d26ced986daa8fe2ab62 (patch)
treec082b5d863efa1f6d87b5341c2911f4c9282111c /toolkit
parent6fd1452bc1bd5bb7ccd22e1a0af075af9fa3acc6 (diff)
INTEGRATION: CWS dba20blocker (1.53.32); FILE MERGED
2005/06/23 10:56:24 fs 1.53.32.1: copying fix for #i47502# into this CWS
Diffstat (limited to 'toolkit')
-rw-r--r--toolkit/source/awt/vclxwindow.cxx104
1 files changed, 100 insertions, 4 deletions
diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx
index 7db700c2e84c..431f50afaedf 100644
--- a/toolkit/source/awt/vclxwindow.cxx
+++ b/toolkit/source/awt/vclxwindow.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: vclxwindow.cxx,v $
*
- * $Revision: 1.53 $
+ * $Revision: 1.54 $
*
- * last change: $Author: rt $ $Date: 2005-03-31 13:24:56 $
+ * last change: $Author: obo $ $Date: 2005-07-08 10:27:53 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -155,6 +155,9 @@
#ifndef COMPHELPER_ASYNCNOTIFICATION_HXX
#include <comphelper/asyncnotification.hxx>
#endif
+#ifndef TOOLKIT_INC_TOOLKIT_HELPER_SOLARRELEASE_HXX
+#include <toolkit/helper/solarrelease.hxx>
+#endif
using ::com::sun::star::style::VerticalAlignment;
using ::com::sun::star::style::VerticalAlignment_TOP;
@@ -162,6 +165,26 @@ using ::com::sun::star::style::VerticalAlignment_MIDDLE;
using ::com::sun::star::style::VerticalAlignment_BOTTOM;
using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE;
+//#define SYNCHRON_NOTIFICATION
+ // define this for notifying mouse events synchronously when they happen
+ // disadvantage: potential of deadlocks, since this means that the
+ // SolarMutex is locked when the listener is called
+ // See http://www.openoffice.org/issues/show_bug.cgi?id=40583 for an example
+ // deadlock
+//#define THREADED_NOTIFICATION
+ // define this for notifying mouse events asynchronously, in a dedicated thread
+ // This is what I'd like to use. However, there's some Windows API code
+ // which doesn't like being called in the non-main thread, and we didn't
+ // find out which one :(
+ // See http://www.openoffice.org/issues/show_bug.cgi?id=47502 for an example
+ // of a bug triggered by asynchronous notification in a foreign thread
+
+// If none of the above is defined, then mouse events are notified asynchronously
+// in the main thread, using PostUserEvent.
+// disadvantage: The event we're posting is delayed until the next event
+// reschedule. Normally, this is virtually immediately, but there's no guarantee
+// ....
+
//====================================================================
//= VCLXWindowImpl
//====================================================================
@@ -175,13 +198,22 @@ class SAL_DLLPRIVATE VCLXWindowImpl : public ::comphelper::IEventProcessor
private:
typedef ::comphelper::EventObjectHolder< ::com::sun::star::awt::MouseEvent >
MouseEventType;
+ typedef ::std::vector< ::rtl::Reference< ::comphelper::EventDescription > >
+ EventArray;
typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
ComponentReference;
private:
VCLXWindow& mrAntiImpl;
::vos::IMutex& mrMutex;
+#ifdef THREADED_NOTIFICATION
::comphelper::AsyncEventNotifier* mpAsyncNotifier;
+#else
+#if !defined( SYNCHRON_NOTIFICATION )
+ EventArray maEvents;
+ sal_Int32 mnEventId;
+#endif
+#endif
public:
/** ctor
@@ -203,13 +235,24 @@ protected:
// IEventProcessor
virtual void processEvent( const ::comphelper::EventDescription& _rEvent );
virtual ComponentReference getComponent();
+
+#if !defined( SYNCHRON_NOTIFICATION ) && !defined( THREADED_NOTIFICATION )
+private:
+ DECL_LINK( OnProcessEvent, void* );
+#endif
};
//--------------------------------------------------------------------
VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex )
:mrAntiImpl( _rAntiImpl )
,mrMutex( _rMutex )
+#ifdef THREADED_NOTIFICATION
,mpAsyncNotifier( NULL )
+#else
+#ifndef SYNCHRON_NOTIFICATION
+ ,mnEventId( 0 )
+#endif
+#endif
{
}
@@ -217,28 +260,81 @@ VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex )
void VCLXWindowImpl::disposing()
{
::vos::OGuard aGuard( mrMutex );
+#ifdef THREADED_NOTIFICATION
if ( mpAsyncNotifier )
{
mpAsyncNotifier->release();
mpAsyncNotifier = NULL;
}
+#else
+#ifndef SYNCHRON_NOTIFICATION
+ if ( mnEventId )
+ Application::RemoveUserEvent( mnEventId );
+ mnEventId = 0;
+#endif
+#endif
}
//--------------------------------------------------------------------
void VCLXWindowImpl::notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rMouseEvent, sal_uInt16 _nType )
{
- ::vos::OGuard aGuard( mrMutex );
+ ::vos::OClearableGuard aGuard( mrMutex );
if ( mrAntiImpl.GetMouseListeners().getLength() )
{
+ ::rtl::Reference< ::comphelper::EventDescription > aEvent( new MouseEventType( _rMouseEvent, _nType ) );
+#ifdef THREADED_NOTIFICATION
if ( !mpAsyncNotifier )
{
mpAsyncNotifier = new ::comphelper::AsyncEventNotifier( this );
mpAsyncNotifier->acquire();
mpAsyncNotifier->create();
}
- mpAsyncNotifier->addEvent( new MouseEventType( _rMouseEvent, _nType ) );
+ mpAsyncNotifier->addEvent( aEvent );
+#else
+ #ifdef SYNCHRON_NOTIFICATION
+ aGuard.clear();
+ processEvent( *aEvent );
+ #else
+ maEvents.push_back( aEvent );
+ if ( !mnEventId )
+ mnEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessEvent ) );
+ #endif
+#endif
+ }
+}
+
+#if !defined( SYNCHRON_NOTIFICATION ) && !defined( THREADED_NOTIFICATION )
+//--------------------------------------------------------------------
+IMPL_LINK( VCLXWindowImpl, OnProcessEvent, void*, NOINTERESTEDIN )
+{
+ // work on a copy of the events array
+ EventArray aEventsCopy;
+ {
+ ::vos::OGuard aGuard( mrMutex );
+ aEventsCopy = maEvents;
+ maEvents.clear();
+
+ if ( !mnEventId )
+ // we were disposed while waiting for the mutex to lock
+ return 1L;
+
+ mnEventId = 0;
+ }
+
+ {
+ ::toolkit::ReleaseSolarMutex aReleaseSolar;
+ for ( EventArray::const_iterator loop = aEventsCopy.begin();
+ loop != aEventsCopy.end();
+ ++loop
+ )
+ {
+ processEvent( *(*loop) );
+ }
}
+
+ return 0L;
}
+#endif
//--------------------------------------------------------------------
void VCLXWindowImpl::processEvent( const ::comphelper::EventDescription& _rEvent )