summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-06-10 12:08:00 +0100
committerMichael Meeks <michael.meeks@collabora.com>2015-06-10 17:27:20 +0100
commit48c2815dd20cf20eeec8bb4e003000f4a3d13291 (patch)
tree19596543beea4e4f56d1d06f429e575f596f0ad7 /vcl
parentef4fd9c52f16e6d242f999dd87170e6cac07230d (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.cxx26
-rw-r--r--vcl/source/app/idle.cxx25
-rw-r--r--vcl/source/app/scheduler.cxx15
-rw-r--r--vcl/source/app/timer.cxx2
-rw-r--r--vcl/source/window/window.cxx2
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() )