From 2bc51a33ae4089d88a3a8a3e5fb56afafac69d35 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 25 May 2007 00:51:08 +0000 Subject: add 'spinner' (non-idle detection) --- lib/gdi/grc.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'lib/gdi/grc.cpp') diff --git a/lib/gdi/grc.cpp b/lib/gdi/grc.cpp index 736630a8..b3ad2ccc 100644 --- a/lib/gdi/grc.cpp +++ b/lib/gdi/grc.cpp @@ -32,6 +32,7 @@ gRC::gRC(): rp(0), wp(0) else eDebug("RC thread created successfully"); #endif + m_spinner_enabled = 0; } DEFINE_REF(gRC); @@ -131,8 +132,46 @@ void *gRC::thread() } #ifndef SYNC_PAINT while(rp == wp) - pthread_cond_wait(&cond, &mutex); - pthread_mutex_unlock(&mutex); + { + + /* when the main thread is non-idle for a too long time without any display output, + we want to display a spinner. */ + + struct timeval time; + struct timespec timeout; + gettimeofday(&time, NULL); + timeout.tv_sec = time.tv_sec; + timeout.tv_nsec = time.tv_usec * 1000; + + if (m_spinner_enabled) + timeout.tv_nsec += 100*1000*1000; + else + timeout.tv_nsec += 500*1000*1000; + + /* yes, this is required. */ + if (timeout.tv_nsec > 1000*1000*1000) + { + timeout.tv_nsec -= 1000*1000*1000; + timeout.tv_sec++; + } + + int idle = 1; + + if (pthread_cond_timedwait(&cond, &mutex, &timeout) == ETIMEDOUT) + { + if (eApp && !eApp->isIdle()) + idle = 0; + } + + pthread_mutex_unlock(&mutex); + + if (!idle) + { + enableSpinner(); + eDebug("main thread is non-idle! display spinner!"); + } else + disableSpinner(); + } #endif } } @@ -152,6 +191,39 @@ gRC *gRC::getInstance() return instance; } +void gRC::enableSpinner() +{ + if (!m_spinner_dc) + { + eDebug("no spinner DC!"); + return; + } + + m_spinner_enabled = 1; + + gOpcode o; + o.opcode = m_spinner_enabled ? gOpcode::incrementSpinner : gOpcode::enableSpinner; + m_spinner_dc->exec(&o); +} + +void gRC::disableSpinner() +{ + if (!m_spinner_enabled) + return; + + if (!m_spinner_dc) + { + eDebug("no spinner DC!"); + return; + } + + m_spinner_enabled = 0; + + gOpcode o; + o.opcode = gOpcode::disableSpinner; + m_spinner_dc->exec(&o); +} + static int gPainter_instances; gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance()) @@ -678,6 +750,12 @@ void gDC::exec(gOpcode *o) break; case gOpcode::flush: break; + case gOpcode::enableSpinner: + break; + case gOpcode::disableSpinner: + break; + case gOpcode::incrementSpinner: + break; default: eFatal("illegal opcode %d. expect memory leak!", o->opcode); } -- cgit v1.2.3