diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-06-10 12:08:00 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-06-10 17:27:20 +0100 |
commit | 48c2815dd20cf20eeec8bb4e003000f4a3d13291 (patch) | |
tree | 19596543beea4e4f56d1d06f429e575f596f0ad7 /vcl | |
parent | ef4fd9c52f16e6d242f999dd87170e6cac07230d (diff) |
tdf#91727 - Unwind non-dispatch of idle handlers.
This clobbers the functionality from commit:
06d731428ef6cf93c7333e8228bfb6088853b52f
make idle timers actually activate only when idle
Since now all rendering and re-sizing is done in idle handlers it
does effectively the opposite of what was intended. A better solution
would allow special-casing the processing of just rendering,
re-sizing and window management to spin for eg. progress bar
rendering.
Also add helpful debugging labels to the idle & timeouts.
Also cleanup the Idle vs. Scheduler handling.
Also ensure that starting an Idle triggers a mainloop wakeup.
Also add a unit test.
Change-Id: Ifb0756714378fdb790be599b93c7a3ac1f9209e6
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/qa/cppunit/timer.cxx | 26 | ||||
-rw-r--r-- | vcl/source/app/idle.cxx | 25 | ||||
-rw-r--r-- | vcl/source/app/scheduler.cxx | 15 | ||||
-rw-r--r-- | vcl/source/app/timer.cxx | 2 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 2 |
5 files changed, 58 insertions, 12 deletions
diff --git a/vcl/qa/cppunit/timer.cxx b/vcl/qa/cppunit/timer.cxx index 976853c88e7b..12110b7fc3bf 100644 --- a/vcl/qa/cppunit/timer.cxx +++ b/vcl/qa/cppunit/timer.cxx @@ -18,6 +18,10 @@ #include <vcl/timer.hxx> #include <vcl/idle.hxx> #include <vcl/svapp.hxx> +#include "svdata.hxx" +#include "salinst.hxx" + +// #define TEST_WATCHDOG /// Avoid our timer tests just wedging the build if they fail. class WatchDog : public osl::Thread @@ -47,6 +51,7 @@ class TimerTest : public test::BootstrapFixture public: TimerTest() : BootstrapFixture(true, false) {} + void testIdleMainloop(); void testIdle(); #ifdef TEST_WATCHDOG void testWatchdog(); @@ -58,6 +63,7 @@ public: CPPUNIT_TEST_SUITE(TimerTest); CPPUNIT_TEST(testIdle); + CPPUNIT_TEST(testIdleMainloop); #ifdef TEST_WATCHDOG CPPUNIT_TEST(testWatchdog); #endif @@ -105,7 +111,25 @@ void TimerTest::testIdle() bool bTriggered = false; IdleBool aTest( bTriggered ); Scheduler::ProcessTaskScheduling(false); - CPPUNIT_ASSERT_MESSAGE("watchdog triggered", bTriggered); + CPPUNIT_ASSERT_MESSAGE("idle triggered", bTriggered); +} + +// tdf#91727 +void TimerTest::testIdleMainloop() +{ + bool bTriggered = false; + IdleBool aTest( bTriggered ); + while (!bTriggered) + { + ImplSVData* pSVData = ImplGetSVData(); + + // can't test this via Application::Yield since this + // also processes all tasks directly via the scheduler. + pSVData->maAppData.mnDispatchLevel++; + pSVData->mpDefInst->Yield( true, false ); + pSVData->maAppData.mnDispatchLevel--; + } + CPPUNIT_ASSERT_MESSAGE("mainloop idle triggered", bTriggered); } // -------------------------------------------------------------------- diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx index 7fe239d199f7..0dd8593bff84 100644 --- a/vcl/source/app/idle.cxx +++ b/vcl/source/app/idle.cxx @@ -18,6 +18,8 @@ */ #include <vcl/idle.hxx> +#include <vcl/timer.hxx> +#include "svdata.hxx" void Idle::Invoke() { @@ -31,7 +33,7 @@ Idle& Idle::operator=( const Idle& rIdle ) return *this; } -Idle::Idle() : Scheduler() +Idle::Idle( const sal_Char *pDebugName ) : Scheduler( pDebugName ) { } @@ -40,4 +42,25 @@ Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle) maIdleHdl = rIdle.maIdleHdl; } +void Idle::Start() +{ + Scheduler::Start(); + ImplSVData* pSVData = ImplGetSVData(); + Timer::ImplStartTimer( pSVData, 0 ); +} + +bool Idle::ReadyForSchedule( bool bTimer ) +{ + // 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 +} + +sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTime */ ) +{ + return 1; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index 20b11dc4c922..c3cea781e6b8 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -120,6 +120,7 @@ void Scheduler::ProcessTaskScheduling( bool bTimer ) sal_uInt64 nMinPeriod = MAX_TIMER_PERIOD; pSVData->mnUpdateStack++; + // tdf#91727 - NB. bTimer is ultimately not used if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer))) { pSchedulerData->mnUpdateTime = nTime; @@ -164,18 +165,12 @@ void Scheduler::ProcessTaskScheduling( bool bTimer ) pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; } else + { Timer::ImplStartTimer( pSVData, nMinPeriod ); + } pSVData->mnUpdateStack--; } -sal_uInt64 Scheduler::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) -{ - // this period is only useful for timer - // so in this implementation it' only a pass through - (void)nTime; - return nMinPeriod; -} - void Scheduler::SetPriority( SchedulerPriority ePriority ) { mePriority = ePriority; @@ -235,8 +230,9 @@ Scheduler& Scheduler::operator=( const Scheduler& rScheduler ) return *this; } -Scheduler::Scheduler(): +Scheduler::Scheduler(const sal_Char *pDebugName): mpSchedulerData(NULL), + mpDebugName(pDebugName), mePriority(SchedulerPriority::HIGH), mbActive(false) { @@ -244,6 +240,7 @@ Scheduler::Scheduler(): Scheduler::Scheduler( const Scheduler& rScheduler ): mpSchedulerData(NULL), + mpDebugName(rScheduler.mpDebugName), mePriority(rScheduler.mePriority), mbActive(false) { diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx index a49f4f5ed320..7d92283b6466 100644 --- a/vcl/source/app/timer.cxx +++ b/vcl/source/app/timer.cxx @@ -98,7 +98,7 @@ void Timer::InitSystemTimer() } } -Timer::Timer() : Scheduler() +Timer::Timer(const sal_Char *pDebugName) : Scheduler(pDebugName) { mnTimeout = 1; mbAuto = false; diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 497fc42de8bf..9754f33e1f5a 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -1058,9 +1058,11 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p { mpWindowImpl->mpFrameData->maPaintIdle.SetPriority( SchedulerPriority::REPAINT ); mpWindowImpl->mpFrameData->maPaintIdle.SetIdleHdl( LINK( this, Window, ImplHandlePaintHdl ) ); + mpWindowImpl->mpFrameData->maPaintIdle.SetDebugName( "vcl::Window maPaintIdle" ); } mpWindowImpl->mpFrameData->maResizeIdle.SetPriority( SchedulerPriority::RESIZE ); mpWindowImpl->mpFrameData->maResizeIdle.SetIdleHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) ); + mpWindowImpl->mpFrameData->maResizeIdle.SetDebugName( "vcl::Window maResizeIdle" ); mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = false; if ( pRealParent && IsTopWindow() ) |