Extracted mouse polling out of the composite timer to allow effects to

detect mouse movement and modifier key changes even when KWin is idle.
As the track mouse effect requires polling to always be active disabling
it by default to prevent wasting CPU usage in the default install.

svn path=/trunk/KDE/kdebase/workspace/; revision=919711
This commit is contained in:
Lucas Murray 2009-02-01 15:16:52 +00:00
parent 0aa8cd610f
commit 752d5fa642
17 changed files with 94 additions and 5 deletions

View file

@ -336,11 +336,8 @@ void Workspace::performCompositing()
}
if( !scene->waitSyncAvailable())
nextPaintReference = QTime::currentTime();
checkCursorPos();
if((( repaints_region.isEmpty() && !windowRepaintsPending()) // no damage
|| !overlay_visible ) // nothing is visible anyway
// HACK: don't idle during active full screen effect so that mouse events are not dropped (bug #177226)
&& !static_cast< EffectsHandlerImpl* >( effects )->activeFullScreenEffect() )
|| !overlay_visible )) // nothing is visible anyway
{
scene->idle();
// Note: It would seem here we should undo suspended unredirect, but when scenes need
@ -404,6 +401,11 @@ void Workspace::performCompositing()
#endif
}
void Workspace::performMousePoll()
{
checkCursorPos();
}
bool Workspace::windowRepaintsPending() const
{
foreach( Toplevel* c, clients )
@ -430,6 +432,16 @@ void Workspace::setCompositeTimer()
compositeTimer.start( qBound( 0, nextPaintReference.msecsTo( QTime::currentTime() ), 250 ) % compositeRate );
}
void Workspace::startMousePolling()
{
mousePollingTimer.start( 20 ); // 50Hz. TODO: How often do we really need to poll?
}
void Workspace::stopMousePolling()
{
mousePollingTimer.stop();
}
bool Workspace::createOverlay()
{
assert( overlay == None );

View file

@ -52,6 +52,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
, keyboard_grab_effect( NULL )
, fullscreen_effect( 0 )
, next_window_quad_type( EFFECT_QUAD_TYPE_START )
, mouse_poll_ref_count( 0 )
{
reconfigure();
}
@ -354,6 +355,21 @@ void EffectsHandlerImpl::grabbedKeyboardEvent( QKeyEvent* e )
keyboard_grab_effect->grabbedKeyboardEvent( e );
}
void EffectsHandlerImpl::startMousePolling()
{
if( !mouse_poll_ref_count ) // Start timer if required
Workspace::self()->startMousePolling();
mouse_poll_ref_count++;
}
void EffectsHandlerImpl::stopMousePolling()
{
assert( mouse_poll_ref_count );
mouse_poll_ref_count--;
if( !mouse_poll_ref_count ) // Stop timer if required
Workspace::self()->stopMousePolling();
}
bool EffectsHandlerImpl::hasKeyboardGrab() const
{
return keyboard_grab_effect != NULL;

View file

@ -65,6 +65,8 @@ class EffectsHandlerImpl : public EffectsHandler
virtual QPoint cursorPos() const;
virtual bool grabKeyboard( Effect* effect );
virtual void ungrabKeyboard();
virtual void startMousePolling();
virtual void stopMousePolling();
virtual EffectWindow* findWindow( WId id ) const;
virtual EffectWindowList stackingOrder() const;
virtual void setElevatedWindow( EffectWindow* w, bool set );
@ -168,6 +170,7 @@ class EffectsHandlerImpl : public EffectsHandler
QMultiMap< int, EffectPair > effect_order;
QHash< long, int > registered_atoms;
int next_window_quad_type;
int mouse_poll_ref_count;
};
class EffectWindowImpl : public EffectWindow

View file

@ -1537,6 +1537,7 @@ void CubeEffect::setActive( bool active )
{
if( active )
{
effects->startMousePolling();
activated = true;
activeScreen = effects->activeScreen();
if( !slide )
@ -1574,6 +1575,7 @@ void CubeEffect::setActive( bool active )
}
else
{
effects->stopMousePolling();
schedule_close = true;
// we have to add a repaint, to start the deactivating
effects->addRepaintFull();

View file

@ -42,6 +42,7 @@ LookingGlassEffect::LookingGlassEffect() : QObject(), ShaderEffect("lookingglass
{
zoom = 1.0f;
target_zoom = 1.0f;
polling = false;
actionCollection = new KActionCollection( this );
actionCollection->setConfigGlobal(true);
@ -83,6 +84,11 @@ void LookingGlassEffect::zoomIn()
{
target_zoom = qMin(7.0, target_zoom + 0.5);
setEnabled( true );
if( !polling )
{
polling = true;
effects->startMousePolling();
}
effects->addRepaint( cursorPos().x() - radius, cursorPos().y() - radius, 2*radius, 2*radius );
}
@ -94,6 +100,11 @@ void LookingGlassEffect::zoomOut()
target_zoom = 1;
setEnabled( false );
}
if( polling )
{
polling = false;
effects->stopMousePolling();
}
effects->addRepaint( cursorPos().x() - radius, cursorPos().y() - radius, 2*radius, 2*radius );
}

View file

@ -54,6 +54,7 @@ class LookingGlassEffect : public QObject, public ShaderEffect
private:
double zoom;
double target_zoom;
bool polling; // Mouse polling
int radius;
int initialradius;
KActionCollection* actionCollection;

View file

@ -42,6 +42,7 @@ const int FRAME_WIDTH = 5;
MagnifierEffect::MagnifierEffect()
: zoom( 1 )
, target_zoom( 1 )
, polling( false )
{
KActionCollection* actionCollection = new KActionCollection( this );
KAction* a;
@ -144,6 +145,11 @@ QRect MagnifierEffect::magnifierArea( QPoint pos ) const
void MagnifierEffect::zoomIn()
{
target_zoom *= 1.2;
if( !polling )
{
polling = true;
effects->startMousePolling();
}
effects->addRepaint( magnifierArea().adjusted( -FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH ));
}
@ -152,6 +158,11 @@ void MagnifierEffect::zoomOut()
target_zoom /= 1.2;
if( target_zoom < 1 )
target_zoom = 1;
if( polling )
{
polling = false;
effects->stopMousePolling();
}
effects->addRepaint( magnifierArea().adjusted( -FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH ));
}

View file

@ -47,6 +47,7 @@ class MagnifierEffect
QRect magnifierArea( QPoint pos = cursorPos()) const;
double zoom;
double target_zoom;
bool polling; // Mouse polling
QSize magnifier_size;
};

View file

@ -58,6 +58,12 @@ MouseMarkEffect::MouseMarkEffect()
connect( a, SIGNAL( triggered( bool )), this, SLOT( clearLast()));
reconfigure( ReconfigureAll );
arrow_start = NULL_POINT;
effects->startMousePolling(); // We require it to detect activation as well
}
MouseMarkEffect::~MouseMarkEffect()
{
effects->stopMousePolling();
}
void MouseMarkEffect::reconfigure( ReconfigureFlags )

View file

@ -33,6 +33,7 @@ class MouseMarkEffect
Q_OBJECT
public:
MouseMarkEffect();
~MouseMarkEffect();
virtual void reconfigure( ReconfigureFlags );
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
virtual void mouseChanged( const QPoint& pos, const QPoint& old,

View file

@ -48,10 +48,12 @@ TrackMouseEffect::TrackMouseEffect()
, angle( 0 )
, texture( NULL )
{
effects->startMousePolling(); // We require it to detect activation as well
}
TrackMouseEffect::~TrackMouseEffect()
{
effects->stopMousePolling();
delete texture;
}

View file

@ -120,5 +120,5 @@ X-KDE-PluginInfo-Version=0.1.0
X-KDE-PluginInfo-Category=Accessibility
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-PluginInfo-EnabledByDefault=false
X-KDE-Library=kwin4_effect_builtins

View file

@ -32,6 +32,7 @@ KWIN_EFFECT( zoom, ZoomEffect )
ZoomEffect::ZoomEffect()
: zoom( 1 )
, target_zoom( 1 )
, polling( false )
{
KActionCollection* actionCollection = new KActionCollection( this );
KAction* a;
@ -82,6 +83,11 @@ void ZoomEffect::postPaintScreen()
void ZoomEffect::zoomIn()
{
target_zoom *= 1.2;
if( !polling )
{
polling = true;
effects->startMousePolling();
}
effects->addRepaintFull();
}
@ -90,6 +96,11 @@ void ZoomEffect::zoomOut()
target_zoom /= 1.2;
if( target_zoom < 1 )
target_zoom = 1;
if( polling )
{
polling = false;
effects->stopMousePolling();
}
effects->addRepaintFull();
}

View file

@ -45,6 +45,7 @@ class ZoomEffect
private:
double zoom;
double target_zoom;
bool polling; // Mouse polling
};
} // namespace

View file

@ -508,6 +508,10 @@ class KWIN_EXPORT EffectsHandler
virtual bool grabKeyboard( Effect* effect ) = 0;
virtual void ungrabKeyboard() = 0;
// Mouse polling
virtual void startMousePolling() = 0;
virtual void stopMousePolling() = 0;
virtual void checkElectricBorder(const QPoint &pos, Time time) = 0;
virtual void reserveElectricBorder( ElectricBorder border ) = 0;
virtual void unreserveElectricBorder( ElectricBorder border ) = 0;

View file

@ -354,6 +354,7 @@ void Workspace::init()
connect( &reconfigureTimer, SIGNAL( timeout() ), this, SLOT( slotReconfigure() ));
connect( &updateToolWindowsTimer, SIGNAL( timeout() ), this, SLOT( slotUpdateToolWindows() ));
connect( &compositeTimer, SIGNAL( timeout() ), SLOT( performCompositing() ));
connect( &mousePollingTimer, SIGNAL( timeout() ), SLOT( performMousePoll() ));
connect( KGlobalSettings::self(), SIGNAL( appearanceChanged() ), this, SLOT( reconfigure() ));
connect( KGlobalSettings::self(), SIGNAL( settingsChanged(int) ), this, SLOT( slotSettingsChanged(int) ));

View file

@ -357,6 +357,10 @@ class Workspace : public QObject, public KDecorationDefines
void checkUnredirect( bool force = false );
void checkCompositeTimer();
// Mouse polling
void startMousePolling();
void stopMousePolling();
public slots:
void addRepaintFull();
void refresh();
@ -517,6 +521,7 @@ class Workspace : public QObject, public KDecorationDefines
void setPopupClientOpacity( QAction* action );
void setupCompositing();
void performCompositing();
void performMousePoll();
void lostCMSelection();
void updateElectricBorders();
void resetCursorPosTime();
@ -765,6 +770,7 @@ class Workspace : public QObject, public KDecorationDefines
QTimer compositeTimer;
QTime lastCompositePaint;
QTime nextPaintReference;
QTimer mousePollingTimer;
int compositeRate;
QRegion repaints_region;
Window overlay; // XComposite overlay window