summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Madl <tobias.madl.dev@gmail.com>2014-10-30 20:07:59 +0100
committerMichael Meeks <michael.meeks@collabora.com>2014-11-05 20:59:44 +0000
commitd6e89e7516271d246b255ec5ebc752713da3dfd5 (patch)
treebcbcf58593f6191eb88057f2da2ea8ff2fa15410
parent9632045906baf165076d11a97f45b153d8e2acb7 (diff)
Basic Idle handler implementation
An idle handler will ultimately be a zero time timeout with prioritisation layered on top of that. Change-Id: I3f0802d5001172fc7b8409274bc5a3632e5dad34
-rw-r--r--include/vcl/timer.hxx36
-rw-r--r--vcl/inc/window.h4
-rw-r--r--vcl/source/app/timer.cxx57
-rw-r--r--vcl/source/window/paint.cxx16
-rw-r--r--vcl/source/window/window.cxx14
-rw-r--r--vcl/source/window/winproc.cxx2
6 files changed, 111 insertions, 18 deletions
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index d3ebe1a256e5..10dd3fca730f 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -73,6 +73,42 @@ public:
AutoTimer& operator=( const AutoTimer& rTimer );
};
+enum IdlePriority {
+ VCL_IDLE_PRIORITY_HIGHEST, // -> 0ms
+ VCL_IDLE_PRIORITY_HIGH, // -> 1ms
+ VCL_IDLE_PRIORITY_REPAINT, // -> 30ms
+ VCL_IDLE_PRIORITY_RESIZE, // -> 50ms
+ VCL_IDLE_PRIORITY_MEDIUM, // -> 50ms
+ VCL_IDLE_PRIORITY_LOW, // -> 100ms
+ VCL_IDLE_PRIORITY_LOWER, // -> 200ms
+ VCL_IDLE_PRIORITY_LOWEST // -> 400ms
+};
+
+
+// To port from Timer -> Idle switch class name,
+// s/Timeout/DoIdle/ etc. and select priority
+class VCL_DLLPUBLIC Idle : public Timer
+{
+ public:
+ Idle();
+ Idle( IdlePriority ePriority );
+ virtual ~Idle();
+
+ void SetPriority( IdlePriority ePriority );
+
+ /// Make it possible to associate a callback with this idle handler
+ /// of course, you can also sub-class and override 'DoIdle'
+ void SetIdleHdl( const Link& rLink ) { SetTimeoutHdl( rLink ); }
+ const Link& GetIdleHdl() const { return GetTimeoutHdl(); }
+
+ void Start() { Timer::Start(); }
+ void Stop() { Timer::Stop(); }
+
+ virtual void DoIdle();
+
+ virtual void Timeout() SAL_OVERRIDE { DoIdle(); }
+};
+
#endif // INCLUDED_VCL_TIMER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 53d077f200e8..2b2082e75d59 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -127,8 +127,8 @@ struct ImplOverlapData
struct ImplFrameData
{
- Timer maPaintTimer; //< paint timer
- Timer maResizeTimer; //< resize timer
+ Idle maPaintIdle; //< paint idle handler
+ Idle maResizeIdle; //< resize timer
InputContext maOldInputContext; //< last set Input Context
vcl::Window* mpNextFrame; //< next frame window
vcl::Window* mpFirstOverlap; //< first overlap vcl::Window
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index ecbfa7467cdc..5f706abcb88a 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -336,4 +336,61 @@ AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
return *this;
}
+Idle::Idle()
+ : Timer()
+{
+ SetPriority(VCL_IDLE_PRIORITY_LOWEST);
+}
+
+Idle::Idle( IdlePriority ePriority )
+ : Timer()
+{
+ SetPriority( ePriority );
+}
+
+void Idle::SetPriority( IdlePriority ePriority )
+{
+ sal_uLong nTimeoutMS = 0;
+
+ // Ultimately this will just be a sort key in a work queue.
+ switch (ePriority) {
+ case VCL_IDLE_PRIORITY_HIGHEST:
+ nTimeoutMS = 0;
+ break;
+ case VCL_IDLE_PRIORITY_HIGH:
+ nTimeoutMS = 1;
+ break;
+ case VCL_IDLE_PRIORITY_REPAINT:
+ nTimeoutMS = 30;
+ break;
+ case VCL_IDLE_PRIORITY_RESIZE:
+ nTimeoutMS = 50;
+ break;
+ case VCL_IDLE_PRIORITY_MEDIUM:
+ nTimeoutMS = 50;
+ break;
+ case VCL_IDLE_PRIORITY_LOW:
+ nTimeoutMS = 100;
+ break;
+ case VCL_IDLE_PRIORITY_LOWER:
+ nTimeoutMS = 200;
+ break;
+ case VCL_IDLE_PRIORITY_LOWEST:
+ default:
+ nTimeoutMS = 400;
+ break;
+ }
+ SetTimeout( nTimeoutMS );
+}
+
+void Idle::DoIdle()
+{
+ maTimeoutHdl.Call( this );
+}
+
+
+Idle::~Idle()
+{
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index ce10abae4ae3..7ec329cc1388 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -283,8 +283,8 @@ void Window::ImplCallOverlapPaint()
void Window::ImplPostPaint()
{
- if ( !ImplDoTiledRendering() && !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
- mpWindowImpl->mpFrameData->maPaintTimer.Start();
+ if ( !ImplDoTiledRendering() && !mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
+ mpWindowImpl->mpFrameData->maPaintIdle.Start();
}
IMPL_LINK_NOARG(Window, ImplHandlePaintHdl)
@@ -292,14 +292,14 @@ IMPL_LINK_NOARG(Window, ImplHandlePaintHdl)
// save paint events until layout is done
if (!ImplDoTiledRendering() && IsSystemWindow() && static_cast<const SystemWindow*>(this)->hasPendingLayout())
{
- mpWindowImpl->mpFrameData->maPaintTimer.Start();
+ mpWindowImpl->mpFrameData->maPaintIdle.Start();
return 0;
}
// save paint events until resizing is done
if( !ImplDoTiledRendering() &&
- mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
- mpWindowImpl->mpFrameData->maPaintTimer.Start();
+ mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
+ mpWindowImpl->mpFrameData->maPaintIdle.Start();
else if ( mpWindowImpl->mbReallyVisible )
ImplCallOverlapPaint();
return 0;
@@ -314,10 +314,10 @@ IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl)
{
ImplHandlePaintHdl(NULL);
}
- else if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
+ else if( mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
{
- mpWindowImpl->mpFrameData->maPaintTimer.Stop();
- mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
+ mpWindowImpl->mpFrameData->maPaintIdle.Stop();
+ mpWindowImpl->mpFrameData->maPaintIdle.GetIdleHdl().Call( NULL );
}
}
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 606a4f551ead..b4468848ef20 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1029,11 +1029,11 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p
mpWindowImpl->mpFrameData->mbSysObjFocus = false;
if (!ImplDoTiledRendering())
{
- mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 );
- mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) );
+ mpWindowImpl->mpFrameData->maPaintIdle.SetPriority( VCL_IDLE_PRIORITY_REPAINT );
+ mpWindowImpl->mpFrameData->maPaintIdle.SetIdleHdl( LINK( this, Window, ImplHandlePaintHdl ) );
}
- mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 );
- mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
+ mpWindowImpl->mpFrameData->maResizeIdle.SetPriority( VCL_IDLE_PRIORITY_RESIZE );
+ mpWindowImpl->mpFrameData->maResizeIdle.SetIdleHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) );
mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = false;
if ( pRealParent && IsTopWindow() )
@@ -2476,11 +2476,11 @@ Size Window::GetSizePixel() const
}
// #i43257# trigger pending resize handler to assure correct window sizes
- if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
+ if( mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
{
ImplDelData aDogtag( this );
- mpWindowImpl->mpFrameData->maResizeTimer.Stop();
- mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL );
+ mpWindowImpl->mpFrameData->maResizeIdle.Stop();
+ mpWindowImpl->mpFrameData->maResizeIdle.GetIdleHdl().Call( NULL );
if( aDogtag.IsDead() )
return Size(0,0);
}
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 62974ca3621e..ee864f4de982 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -1596,7 +1596,7 @@ void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
bStartTimer = false;
if( bStartTimer )
- pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
+ pWindow->ImplGetWindowImpl()->mpFrameData->maResizeIdle.Start();
else
pWindow->ImplCallResize(); // otherwise menus cannot be positioned
}