diff --git a/effects.cpp b/effects.cpp index 98df05e0a0..f847570fb5 100644 --- a/effects.cpp +++ b/effects.cpp @@ -324,6 +324,25 @@ bool EffectsHandlerImpl::hasKeyboardGrab() const return keyboard_grab_effect != NULL; } +void EffectsHandlerImpl::propertyNotify( EffectWindow* c, long atom ) + { + if( !registered_atoms.contains( atom )) + return; + foreach( EffectPair ep, loaded_effects ) + ep.second->propertyNotify( c, atom ); + } + +void EffectsHandlerImpl::registerPropertyType( long atom, bool reg ) + { + if( reg ) + ++registered_atoms[ atom ]; // initialized to 0 if not present yet + else + { + if( --registered_atoms[ atom ] == 0 ) + registered_atoms.remove( atom ); + } + } + void EffectsHandlerImpl::activateWindow( EffectWindow* c ) { if( Client* cl = dynamic_cast< Client* >( static_cast(c)->window())) @@ -1024,6 +1043,42 @@ QRect EffectWindowImpl::contentsRect() const return QRect( toplevel->clientPos(), toplevel->clientSize()); } +QByteArray EffectWindowImpl::readProperty( long atom, long type, int format ) const + { + int len = 32768; + for(;;) + { + unsigned char* data; + Atom rtype; + int rformat; + unsigned long nitems, after; + if( XGetWindowProperty( QX11Info::display(), window()->window(), + atom, 0, len, False, AnyPropertyType, + &rtype, &rformat, &nitems, &after, &data ) == Success ) + { + if( after > 0 ) + { + XFree( data ); + len *= 2; + continue; + } + if( long( rtype ) == type && rformat == format ) + { + QByteArray ret( reinterpret_cast< const char* >( data ), nitems * ( format / 8 )); + XFree( data ); + return ret; + } + else // wrong format, type or something + { + XFree( data ); + return QByteArray(); + } + } + else // XGetWindowProperty() failed + return QByteArray(); + } + } + bool EffectWindowImpl::isMovable() const { if( Client* c = dynamic_cast< Client* >( toplevel )) diff --git a/effects.h b/effects.h index 7151687805..a4aeecfbda 100644 --- a/effects.h +++ b/effects.h @@ -109,6 +109,7 @@ class EffectsHandlerImpl : public EffectsHandler virtual unsigned long xrenderBufferPicture(); virtual void reconfigure(); + virtual void registerPropertyType( long atom, bool reg ); // internal (used by kwin core or compositing code) void startPaint(); @@ -131,6 +132,7 @@ class EffectsHandlerImpl : public EffectsHandler Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers ); void grabbedKeyboardEvent( QKeyEvent* e ); bool hasKeyboardGrab() const; + void propertyNotify( EffectWindow* c, long atom ); bool loadEffect( const QString& name ); void toggleEffect( const QString& name ); @@ -149,6 +151,7 @@ class EffectsHandlerImpl : public EffectsHandler Effect* fullscreen_effect; ToplevelList elevated_windows; QMultiMap< int, EffectPair > effect_order; + QHash< long, int > registered_atoms; }; class EffectWindowImpl : public EffectWindow @@ -192,6 +195,7 @@ class EffectWindowImpl : public EffectWindow virtual bool isUserResize() const; virtual QRect iconGeometry() const; virtual QRect contentsRect() const; + virtual QByteArray readProperty( long atom, long type, int format ) const; virtual bool isDesktop() const; virtual bool isDock() const; diff --git a/events.cpp b/events.cpp index ad1a181cfd..aa03c0c082 100644 --- a/events.cpp +++ b/events.cpp @@ -1724,6 +1724,8 @@ void Toplevel::propertyNotifyEvent( XPropertyEvent* e ) getWindowRole(); break; } + if( effects ) + static_cast< EffectsHandlerImpl* >( effects )->propertyNotify( effectWindow(), e->atom ); } // **************************************** diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index 73e56bef1a..586ba29424 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -131,6 +131,10 @@ void Effect::grabbedKeyboardEvent( QKeyEvent* ) { } +void Effect::propertyNotify( EffectWindow* , long ) + { + } + void Effect::desktopChanged( int ) { } diff --git a/lib/kwineffects.h b/lib/kwineffects.h index cb6b9975fe..9a6702a514 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -40,7 +40,7 @@ along with this program. If not, see . #define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor )) #define KWIN_EFFECT_API_VERSION_MAJOR 0 -#define KWIN_EFFECT_API_VERSION_MINOR 2 +#define KWIN_EFFECT_API_VERSION_MINOR 3 #define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \ KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR ) @@ -247,6 +247,14 @@ class KWIN_EXPORT Effect virtual void mouseChanged( const QPoint& pos, const QPoint& old, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers ); virtual void grabbedKeyboardEvent( QKeyEvent* e ); + /** + Receives events registered for using EffectsHandler::registerPropertyType(). + Use readProperty() to get the property data. + Note that the property may be already set on the window, so doing the same + processing from windowAdded() (e.g. simply calling propertyNotify() from it) + is usually needed. + */ + virtual void propertyNotify( EffectWindow* w, long atom ); virtual void tabBoxAdded( int mode ); virtual void tabBoxClosed(); @@ -405,6 +413,14 @@ class KWIN_EXPORT EffectsHandler virtual unsigned long xrenderBufferPicture() = 0; virtual void reconfigure() = 0; + /** + Makes KWin core watch PropertyNotify events for the given atom, + or stops watching if reg is false (must be called the same number + of times as registering). Events are sent using Effect::propertyNotify(). + Note that even events that haven't been registered for can be received. + */ + virtual void registerPropertyType( long atom, bool reg ) = 0; + /** * Paints given text onto screen, possibly in elided form * @param text @@ -507,6 +523,7 @@ class KWIN_EXPORT EffectWindow */ virtual QRect contentsRect() const = 0; bool hasDecoration() const; + virtual QByteArray readProperty( long atom, long type, int format ) const = 0; virtual QString caption() const = 0; virtual QPixmap icon() const = 0;