[Libreoffice-commits] core.git: vcl/inc vcl/source vcl/unx
Jan-Marek Glogowski
glogow at fbihome.de
Fri Oct 6 13:05:30 UTC 2017
vcl/inc/unx/gendisp.hxx | 2 -
vcl/inc/unx/saldisp.hxx | 2 -
vcl/source/app/salusereventlist.cxx | 1
vcl/unx/generic/app/gendisp.cxx | 4 +-
vcl/unx/generic/app/salinst.cxx | 3 +
vcl/unx/kde4/KDESalDisplay.cxx | 3 -
vcl/unx/kde4/KDEXLib.cxx | 62 ++++++++++++++++++++++++++----------
vcl/unx/kde4/KDEXLib.hxx | 19 ++++++-----
8 files changed, 64 insertions(+), 32 deletions(-)
New commits:
commit 0d24dd25e6f506b5f9128d70d7eb21f0bb4dde89
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Oct 5 18:19:32 2017 +0200
KDE update system loop integration
This updates the system loop integration to be on par with the
other backends. This includes:
1. Process LO user events before other LO events
2. Correctly handle elapsed QTimer events
3. Don't wait-yield in the main thread from a non-main thread
Change-Id: Ia17be032ae39dc4c7bfa44cadd22d85a1b9c4fbd
Reviewed-on: https://gerrit.libreoffice.org/43198
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
diff --git a/vcl/inc/unx/gendisp.hxx b/vcl/inc/unx/gendisp.hxx
index 5c8f5113c300..2d5bc12fcadf 100644
--- a/vcl/inc/unx/gendisp.hxx
+++ b/vcl/inc/unx/gendisp.hxx
@@ -47,7 +47,7 @@ public:
void SendInternalEvent( SalFrame* pFrame, void* pData, SalEvent nEvent = SalEvent::UserEvent );
void CancelInternalEvent( SalFrame* pFrame, void* pData, SalEvent nEvent );
- bool DispatchInternalEvent();
+ bool DispatchInternalEvent( bool bHandleAllCurrentEvent = false );
bool MouseCaptured( const SalFrame *pFrameData ) const
{ return m_pCapture == pFrameData; }
diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx
index 8f96e03630b0..54799149e25c 100644
--- a/vcl/inc/unx/saldisp.hxx
+++ b/vcl/inc/unx/saldisp.hxx
@@ -179,7 +179,7 @@ public:
virtual void StartTimer( sal_uLong nMS );
virtual void StopTimer();
- bool CheckTimeout( bool bExecuteTimers = true );
+ virtual bool CheckTimeout( bool bExecuteTimers = true );
SalI18N_InputMethod* GetInputMethod() const { return m_pInputMethod; }
Display* GetDisplay() const { return m_pDisplay; }
diff --git a/vcl/source/app/salusereventlist.cxx b/vcl/source/app/salusereventlist.cxx
index 6384d8805be4..8f9d76ed313f 100644
--- a/vcl/source/app/salusereventlist.cxx
+++ b/vcl/source/app/salusereventlist.cxx
@@ -51,6 +51,7 @@ bool SalUserEventList::DispatchUserEvents( bool bHandleAllCurrentEvents )
{
osl::MutexGuard aGuard( m_aUserEventsMutex );
+ assert( m_aProcessingUserEvents.empty() );
if( ! m_aUserEvents.empty() )
{
if( bHandleAllCurrentEvents )
diff --git a/vcl/unx/generic/app/gendisp.cxx b/vcl/unx/generic/app/gendisp.cxx
index 1be8606602e0..c83283a7b0e0 100644
--- a/vcl/unx/generic/app/gendisp.cxx
+++ b/vcl/unx/generic/app/gendisp.cxx
@@ -47,9 +47,9 @@ void SalGenericDisplay::emitDisplayChanged()
pAnyFrame->CallCallback( SalEvent::DisplayChanged, nullptr );
}
-bool SalGenericDisplay::DispatchInternalEvent()
+bool SalGenericDisplay::DispatchInternalEvent( bool bHandleAllCurrentEvent )
{
- return DispatchUserEvents( false );
+ return DispatchUserEvents( bHandleAllCurrentEvent );
}
void SalGenericDisplay::SendInternalEvent( SalFrame* pFrame, void* pData, SalEvent nEvent )
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index abd29a78c077..0d30e1d17a99 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -147,7 +147,8 @@ bool X11SalInstance::AnyInput(VclInputFlags nType)
if( (nType & VclInputFlags::TIMER) && (mpXLib && mpXLib->CheckTimeout(false)) )
bRet = true;
- else if (XPending(pDisplay) )
+
+ if( !bRet && XPending(pDisplay) )
{
PredicateReturn aInput;
XEvent aEvent;
diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index 8a2422a3918d..14a753e1c0a1 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -47,9 +47,6 @@ SalKDEDisplay::~SalKDEDisplay()
void SalKDEDisplay::Yield()
{
- if( DispatchInternalEvent() )
- return;
-
// Prevent blocking from Drag'n'Drop events, which may have already have processed the event
if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0)
return;
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index f047ed9fce65..43e055a2c0bb 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -53,6 +53,7 @@ KDEXLib::KDEXLib() :
m_nFakeCmdLineArgs( 0 ),
m_isGlibEventLoopType(false), m_allowKdeDialogs(false),
m_timerEventId( -1 ), m_postUserEventId( -1 )
+ , m_bTimedOut( false )
{
m_timerEventId = QEvent::registerEventType();
m_postUserEventId = QEvent::registerEventType();
@@ -269,22 +270,24 @@ void KDEXLib::socketNotifierActivated( int fd )
bool KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
+ bool bWasEvent = false;
if( !m_isGlibEventLoopType )
{
- bool wasEvent = false;
if( qApp->thread() == QThread::currentThread())
{
// even if we use the LO event loop, still process Qt's events,
// otherwise they can remain unhandled for quite a long while
- wasEvent = processYield( false, bHandleAllCurrentEvents );
+ bWasEvent = processYield( false, bHandleAllCurrentEvents );
}
- return SalXLib::Yield(bWait, bHandleAllCurrentEvents) || wasEvent;
+ return SalXLib::Yield(bWait, bHandleAllCurrentEvents) || bWasEvent;
}
// if we are the main thread (which is where the event processing is done),
// good, just do it
if( qApp->thread() == QThread::currentThread())
{
- return processYield( bWait, bHandleAllCurrentEvents );
+ bWasEvent = processYield( bWait, bHandleAllCurrentEvents );
+ if ( bWasEvent )
+ m_aWaitingYieldCond.set();
}
else
{
@@ -292,23 +295,40 @@ bool KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
// release the yield lock to prevent deadlock with the main thread
// (it's ok to release it here, since even normal processYield() would
// temporarily do it while checking for new events)
- SolarMutexReleaser aReleaser;
- return Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents );
+ {
+ SolarMutexReleaser aReleaser;
+ bWasEvent = Q_EMIT processYieldSignal( false, bHandleAllCurrentEvents );
+ }
+ if ( !bWasEvent && bWait )
+ {
+ m_aWaitingYieldCond.reset();
+ SolarMutexReleaser aReleaser;
+ m_aWaitingYieldCond.wait();
+ bWasEvent = true;
+ }
}
+ return bWasEvent;
}
-/**
- * Quoting the Qt docs: [QAbstractEventDispatcher::processEvents] processes
- * pending events that match flags until there are no more events to process.
- */
-bool KDEXLib::processYield( bool bWait, bool )
+bool KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents )
{
- QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread());
bool wasEvent = false;
- if ( bWait )
+ if ( m_isGlibEventLoopType )
+ {
+ wasEvent = SalKDEDisplay::self()->DispatchInternalEvent( bHandleAllCurrentEvents );
+ if ( !bHandleAllCurrentEvents && wasEvent )
+ return true;
+ }
+
+ /**
+ * Quoting the Qt docs: [QAbstractEventDispatcher::processEvents] processes
+ * pending events that match flags until there are no more events to process.
+ */
+ QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread());
+ if ( bWait && !wasEvent )
wasEvent = dispatcher->processEvents( QEventLoop::WaitForMoreEvents );
else
- wasEvent = dispatcher->processEvents( QEventLoop::AllEvents );
+ wasEvent = dispatcher->processEvents( QEventLoop::AllEvents ) || wasEvent;
return wasEvent;
}
@@ -336,18 +356,28 @@ void KDEXLib::StopTimer()
timeoutTimer.stop();
}
+bool KDEXLib::CheckTimeout( bool bExecuteTimers )
+{
+ if( !m_isGlibEventLoopType )
+ return SalXLib::CheckTimeout( bExecuteTimers );
+ assert( !bExecuteTimers );
+ return m_bTimedOut;
+}
+
void KDEXLib::timeoutActivated()
{
// don't potentially wait in timeout, as QTimer is non-recursive
+ m_bTimedOut = true;
QApplication::postEvent(this, new QEvent(QEvent::Type( m_timerEventId )));
}
void KDEXLib::customEvent(QEvent* e)
{
if( e->type() == m_timerEventId )
+ {
+ m_bTimedOut = false;
X11SalData::Timeout();
- else if( e->type() == m_postUserEventId )
- SalKDEDisplay::self()->DispatchInternalEvent();
+ }
}
void KDEXLib::Wakeup()
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index 4c06104b4c59..452aae8b3286 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -30,13 +30,14 @@
#include <QtCore/QTimer>
#include <unx/salinst.h>
+#include <osl/conditn.hxx>
class VCLKDEApplication;
class KDEXLib : public QObject, public SalXLib
{
Q_OBJECT
- private:
+
bool m_bStartupDone;
std::unique_ptr<VCLKDEApplication> m_pApplication;
std::unique_ptr<char*[]> m_pFreeCmdLineArgs;
@@ -56,23 +57,24 @@ class KDEXLib : public QObject, public SalXLib
bool m_allowKdeDialogs;
int m_timerEventId;
int m_postUserEventId;
+ osl::Condition m_aWaitingYieldCond;
+ bool m_bTimedOut;
- private:
- void setupEventLoop();
+ void setupEventLoop();
- private Q_SLOTS:
+private Q_SLOTS:
void socketNotifierActivated( int fd );
void timeoutActivated();
void startTimeoutTimer();
- static bool processYield( bool bWait, bool bHandleAllCurrentEvents );
+ bool processYield( bool bWait, bool bHandleAllCurrentEvents );
- Q_SIGNALS:
+Q_SIGNALS:
void startTimeoutTimerSignal();
bool processYieldSignal( bool bWait, bool bHandleAllCurrentEvents );
css::uno::Reference< css::ui::dialogs::XFilePicker2 >
createFilePickerSignal( const css::uno::Reference< css::uno::XComponentContext >& );
- public:
+public:
KDEXLib();
virtual ~KDEXLib() override;
@@ -82,6 +84,7 @@ class KDEXLib : public QObject, public SalXLib
virtual void Remove( int fd ) override;
virtual void StartTimer( sal_uLong nMS ) override;
virtual void StopTimer() override;
+ virtual bool CheckTimeout( bool bExecuteTimers = true ) override;
virtual void Wakeup() override;
void TriggerUserEventProcessing();
@@ -90,7 +93,7 @@ class KDEXLib : public QObject, public SalXLib
virtual void customEvent(QEvent* e) override;
- public Q_SLOTS:
+public Q_SLOTS:
css::uno::Reference< css::ui::dialogs::XFilePicker2 >
createFilePicker( const css::uno::Reference< css::uno::XComponentContext >& );
};
More information about the Libreoffice-commits
mailing list