diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-11-24 16:59:29 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-11-24 19:46:02 +0000 |
commit | 87199d3829257420429057336283c55be6ae7481 (patch) | |
tree | 40f63144f9b20cebbaa6cb6fd64184e27c7b192f /vcl | |
parent | 9b52b8999be86e5c6e5f5901b2640b16f08a2323 (diff) |
vcl: re-introduce idle handling.
The idea here is that we should process 'idle' events - like re-paint
after we have processed any OS messages - such as key/mouse input,
window re-size events etc.
The previous approach wasn't achieving this - it was processing a single
idle event each time around the main-loop iteration; urk.
Lubos implemented something -like- this, the vestiges of it need cleaning
up and removing in: 06d731428ef6cf93c7333e8228bfb6088853b52f but it was
disabled (most likely because it broke gtk in tdf#91727, which was itself
broken by using silly values for timeouts in the scheduler (now fixed))
Tested on Windows, gtk, kde4, unx-generic.
Change-Id: I7756bca874779c00f72b372cacb7745d0f189f66
Reviewed-on: https://gerrit.libreoffice.org/20158
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/app/idle.cxx | 5 | ||||
-rw-r--r-- | vcl/source/app/scheduler.cxx | 31 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 9 |
3 files changed, 26 insertions, 19 deletions
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx index 5ce53613bc4d..bba2d050c2c4 100644 --- a/vcl/source/app/idle.cxx +++ b/vcl/source/app/idle.cxx @@ -48,10 +48,7 @@ void Idle::Start() bool Idle::ReadyForSchedule( bool bTimer ) const { - // tdf#91727 - We need to re-work this to allow only UI idle handlers - // and not timeouts to be processed in some limited scenarios - (void)bTimer; - return true; // !bTimer + return !bTimer; } sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 /* nTime */ ) const diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index b5e64e243801..743de911cd22 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -153,7 +153,7 @@ void Scheduler::CallbackTaskScheduling(bool ignore) { // this function is for the saltimer callback (void)ignore; - Scheduler::ProcessTaskScheduling( true ); + Scheduler::ProcessTaskScheduling( false ); } void Scheduler::ProcessTaskScheduling( bool bTimerOnly ) @@ -168,7 +168,7 @@ void Scheduler::ProcessTaskScheduling( bool bTimerOnly ) } } -sal_uInt64 Scheduler::CalculateMinimumTimeout() +sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles ) { // process all pending Tasks // if bTimer True, only handle timer @@ -181,13 +181,11 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout() pSchedulerData = pSVData->mpFirstSchedulerData; while ( pSchedulerData ) { - if( pSchedulerData->mbInScheduler ) - { - pPrevSchedulerData = pSchedulerData; - pSchedulerData = pSchedulerData->mpNext; - } + ImplSchedulerData *pNext = pSchedulerData->mpNext; + // Should Task be released from scheduling? - else if ( pSchedulerData->mbDelete ) + if ( !pSchedulerData->mbInScheduler && + pSchedulerData->mbDelete ) { if ( pPrevSchedulerData ) pPrevSchedulerData->mpNext = pSchedulerData->mpNext; @@ -195,19 +193,24 @@ sal_uInt64 Scheduler::CalculateMinimumTimeout() pSVData->mpFirstSchedulerData = pSchedulerData->mpNext; if ( pSchedulerData->mpScheduler ) pSchedulerData->mpScheduler->mpSchedulerData = nullptr; - ImplSchedulerData* pTempSchedulerData = pSchedulerData; - pSchedulerData = pSchedulerData->mpNext; - delete pTempSchedulerData; + pNext = pSchedulerData->mpNext; + delete pSchedulerData; } else { - nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime ); + if (!pSchedulerData->mbInScheduler) + { + if ( pSchedulerData->mpScheduler->ReadyForSchedule( true ) ) + nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime ); + else + bHasActiveIdles = true; + } pPrevSchedulerData = pSchedulerData; - pSchedulerData = pSchedulerData->mpNext; } + pSchedulerData = pNext; } - // delete clock if no more timers available + // delete clock if no more timers available, if ( !pSVData->mpFirstSchedulerData ) { if ( pSVData->mpSalTimer ) diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 734b5def9f1f..808e743bdbc9 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -477,18 +477,25 @@ inline void ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased { ImplSVData* pSVData = ImplGetSVData(); + bool bHasActiveIdles = false; sal_uInt64 nMinTimeout = 0; if (nReleased == 0) // else thread doesn't have SolarMutex so avoid race - nMinTimeout = Scheduler::CalculateMinimumTimeout(); + nMinTimeout = Scheduler::CalculateMinimumTimeout(bHasActiveIdles); // FIXME: should use returned value as param to DoYield (void)nMinTimeout; + // If we have idles, don't wait for the timeout; check for events + // and come back as quick as possible. + if (bHasActiveIdles) + i_bWait = false; + // TODO: there's a data race here on WNT only because ImplYield may be // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr) // then the only remaining use of mnDispatchLevel is in OSX specific code // so that would effectively eliminate the race on WNT pSVData->maAppData.mnDispatchLevel++; + // do not wait for events if application was already quit; in that // case only dispatch events already available // do not wait for events either if the app decided that it is too busy for timers |