diff --git a/composite.cpp b/composite.cpp index 3579c42ff4..36a3b3fe76 100644 --- a/composite.cpp +++ b/composite.cpp @@ -247,6 +247,7 @@ void Workspace::finishCompositing() delete scene; scene = NULL; compositeTimer.stop(); + mousePollingTimer.stop(); repaints_region = QRegion(); for( ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); @@ -336,11 +337,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 +402,11 @@ void Workspace::performCompositing() #endif } +void Workspace::performMousePoll() + { + checkCursorPos(); + } + bool Workspace::windowRepaintsPending() const { foreach( Toplevel* c, clients ) @@ -430,6 +433,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 ); diff --git a/effects.cpp b/effects.cpp index d45bf41333..e0ebb6a755 100644 --- a/effects.cpp +++ b/effects.cpp @@ -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; diff --git a/effects.h b/effects.h index 8eaeb4fb7c..4bd7412976 100644 --- a/effects.h +++ b/effects.h @@ -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 diff --git a/effects/cube.cpp b/effects/cube.cpp index 9298570e54..894bb14fa5 100644 --- a/effects/cube.cpp +++ b/effects/cube.cpp @@ -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(); diff --git a/effects/lookingglass.cpp b/effects/lookingglass.cpp index a594dc3f52..c362f4e336 100644 --- a/effects/lookingglass.cpp +++ b/effects/lookingglass.cpp @@ -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 ); } diff --git a/effects/lookingglass.h b/effects/lookingglass.h index 367d59fbdc..96b4422002 100644 --- a/effects/lookingglass.h +++ b/effects/lookingglass.h @@ -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; diff --git a/effects/magnifier.cpp b/effects/magnifier.cpp index 0bc65c6694..c64737b789 100644 --- a/effects/magnifier.cpp +++ b/effects/magnifier.cpp @@ -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 )); } diff --git a/effects/magnifier.h b/effects/magnifier.h index 45d467a022..7ed5018846 100644 --- a/effects/magnifier.h +++ b/effects/magnifier.h @@ -47,6 +47,7 @@ class MagnifierEffect QRect magnifierArea( QPoint pos = cursorPos()) const; double zoom; double target_zoom; + bool polling; // Mouse polling QSize magnifier_size; }; diff --git a/effects/mousemark.cpp b/effects/mousemark.cpp index 93ba41cb06..8f5e3fcf33 100644 --- a/effects/mousemark.cpp +++ b/effects/mousemark.cpp @@ -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 ) diff --git a/effects/mousemark.h b/effects/mousemark.h index 217aa61262..11edfb7f4d 100644 --- a/effects/mousemark.h +++ b/effects/mousemark.h @@ -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, diff --git a/effects/trackmouse.cpp b/effects/trackmouse.cpp index 1d3573d05b..91a8481821 100644 --- a/effects/trackmouse.cpp +++ b/effects/trackmouse.cpp @@ -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; } diff --git a/effects/trackmouse.desktop b/effects/trackmouse.desktop index 51ad6164ff..621277d1f5 100644 --- a/effects/trackmouse.desktop +++ b/effects/trackmouse.desktop @@ -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 diff --git a/effects/zoom.cpp b/effects/zoom.cpp index 27c64b1103..8a57e35946 100644 --- a/effects/zoom.cpp +++ b/effects/zoom.cpp @@ -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(); } diff --git a/effects/zoom.h b/effects/zoom.h index d805ce2ea2..44037ccbbf 100644 --- a/effects/zoom.h +++ b/effects/zoom.h @@ -45,6 +45,7 @@ class ZoomEffect private: double zoom; double target_zoom; + bool polling; // Mouse polling }; } // namespace diff --git a/lib/kwineffects.h b/lib/kwineffects.h index dbd10f8b6e..540eb91fa2 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -164,7 +164,7 @@ X-KDE-Library=kwin4_effect_cooleffect #define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor )) #define KWIN_EFFECT_API_VERSION_MAJOR 0 -#define KWIN_EFFECT_API_VERSION_MINOR 57 +#define KWIN_EFFECT_API_VERSION_MINOR 58 #define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \ KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR ) @@ -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; diff --git a/workspace.cpp b/workspace.cpp index c46c6272ba..e5a9e0142e 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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) )); diff --git a/workspace.h b/workspace.h index 1157689d80..b3835c9d6c 100644 --- a/workspace.h +++ b/workspace.h @@ -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