From 649887d6c21005df9c81f75d5bb4c938708c162f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Sat, 30 Sep 2006 15:40:03 +0000 Subject: [PATCH] Looks like using XserverRegion for keeping damage regions wasn't that good idea. Changed to QRegion. svn path=/branches/work/kwin_composite/; revision=590648 --- composite.cpp | 140 ++++++++-------------------------------------- events.cpp | 111 ++++++++++++++++++++++++++++++++---- geometry.cpp | 38 +++++++++---- scene.cpp | 2 +- scene.h | 4 +- scene_basic.cpp | 2 +- scene_basic.h | 2 +- scene_opengl.cpp | 2 +- scene_opengl.h | 2 +- scene_xrender.cpp | 59 ++++++++++++++----- scene_xrender.h | 4 +- toplevel.cpp | 2 - toplevel.h | 7 +-- utils.cpp | 81 +++++++++++++++------------ utils.h | 18 ------ workspace.h | 6 +- 16 files changed, 258 insertions(+), 222 deletions(-) diff --git a/composite.cpp b/composite.cpp index 192e96a0c0..add2dab15a 100644 --- a/composite.cpp +++ b/composite.cpp @@ -69,9 +69,7 @@ void Workspace::finishCompositing() effects = NULL; delete scene; scene = NULL; - if( damage_region != None ) - XFixesDestroyRegion( display(), damage_region ); - damage_region = None; + damage_region = QRegion(); for( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it ) @@ -84,107 +82,41 @@ void Workspace::finishCompositing() } } -void Workspace::addDamage( const QRect& r ) - { - addDamage( r.x(), r.y(), r.width(), r.height()); - } - void Workspace::addDamage( int x, int y, int w, int h ) { if( !compositing()) return; - XRectangle r; - r.x = x; - r.y = y; - r.width = w; - r.height = h; - addDamage( XFixesCreateRegion( display(), &r, 1 ), true ); + damage_region += QRegion( x, y, w, h ); } -void Workspace::addDamage( XserverRegion r, bool destroy ) +void Workspace::addDamage( const QRect& r ) { if( !compositing()) return; - if( damage_region != None ) - { - XFixesUnionRegion( display(), damage_region, damage_region, r ); - if( destroy ) - XFixesDestroyRegion( display(), r ); - } - else - { - if( destroy ) - damage_region = r; - else - { - damage_region = XFixesCreateRegion( display(), NULL, 0 ); - XFixesCopyRegion( display(), damage_region, r ); - } - } - } - -void Workspace::addDamage( Toplevel* c, const QRect& r ) - { - addDamage( c, r.x(), r.y(), r.width(), r.height()); + damage_region += r; } void Workspace::addDamage( Toplevel* c, int x, int y, int w, int h ) { if( !compositing()) return; - XRectangle r; - r.x = x; - r.y = y; - r.width = w; - r.height = h; - addDamage( c, XFixesCreateRegion( display(), &r, 1 ), true ); + addDamage( c, QRect( x, y, w, h )); } -void Workspace::addDamage( Toplevel* c, XserverRegion r, bool destroy ) +void Workspace::addDamage( Toplevel* c, const QRect& r ) { if( !compositing()) return; - if( !destroy ) - { - XserverRegion r2 = XFixesCreateRegion( display(), NULL, 0 ); - XFixesCopyRegion( display(), r2, r ); - r = r2; - destroy = true; - } - scene->transformWindowDamage( c, r ); - if( damage_region != None ) - { - XFixesUnionRegion( display(), damage_region, damage_region, r ); - XFixesDestroyRegion( display(), r ); - } - else - damage_region = r; + QRegion r2( r ); + scene->transformWindowDamage( c, r2 ); + damage_region += r2; } void Workspace::compositeTimeout() { - ToplevelList windows; - foreach( Toplevel* c, clients ) - windows.append( c ); - foreach( Toplevel* c, unmanaged ) - windows.append( c ); - foreach( Toplevel* c, windows ) - { - if( c->damage() != None ) - { - if( damage_region == None ) - damage_region = XFixesCreateRegion( display(), NULL, 0 ); - XserverRegion r = XFixesCreateRegion( display(), NULL, 0 ); - XFixesCopyRegion( display(), r, c->damage()); - scene->transformWindowDamage( c, r ); - XFixesUnionRegion( display(), damage_region, damage_region, r ); - XFixesDestroyRegion( display(), r ); - c->resetDamage(); - } - } - if( damage_region == None ) // no damage + if( damage_region.isEmpty()) // no damage return; - windows.clear(); + ToplevelList windows; Window* children; unsigned int children_count; Window dummy; @@ -202,8 +134,7 @@ void Workspace::compositeTimeout() windows.append( c ); } scene->paint( damage_region, windows ); - XFixesDestroyRegion( display(), damage_region ); - damage_region = None; + damage_region = QRegion(); } //**************************************** @@ -217,6 +148,7 @@ void Toplevel::setupCompositing() if( damage_handle != None ) return; damage_handle = XDamageCreate( display(), handle(), XDamageReportRawRectangles ); + damage_region = QRegion( 0, 0, width(), height()); } void Toplevel::finishCompositing() @@ -228,9 +160,7 @@ void Toplevel::finishCompositing() if( window_pixmap != None ) XFreePixmap( display(), window_pixmap ); window_pixmap = None; - if( damage_region != None ) - XFixesDestroyRegion( display(), damage_region ); - damage_region = None; + damage_region = QRegion(); } void Toplevel::resetWindowPixmap() @@ -251,8 +181,7 @@ Pixmap Toplevel::windowPixmap() const void Toplevel::damageNotifyEvent( XDamageNotifyEvent* e ) { - XserverRegion r = XFixesCreateRegion( display(), &e->area, 1 ); - addDamage( r, true ); + addDamage( e->area.x, e->area.y, e->area.width, e->area.height ); } void Toplevel::addDamage( const QRect& r ) @@ -264,41 +193,18 @@ void Toplevel::addDamage( int x, int y, int w, int h ) { if( !compositing()) return; - XRectangle r; - r.x = x; - r.y = y; - r.width = w; - r.height = h; - addDamage( XFixesCreateRegion( display(), &r, 1 ), true ); - } - -void Toplevel::addDamage( XserverRegion r, bool destroy ) - { - if( !compositing()) - return; - if( damage_region != None ) - { - XFixesUnionRegion( display(), damage_region, damage_region, r ); - if( destroy ) - XFixesDestroyRegion( display(), r ); - } - else - { - if( destroy ) - damage_region = r; - else - { - damage_region = XFixesCreateRegion( display(), NULL, 0 ); - XFixesCopyRegion( display(), damage_region, r ); - } - } + QRect r( x, y, w, h ); + damage_region += r; + r.translate( this->x(), this->y()); + // this could be possibly optimized to damage Workspace only if the toplevel + // is actually visible there and not obscured by something, but I guess + // that's not really worth it + workspace()->addDamage( this, r ); } void Toplevel::resetDamage() { - if( damage_region != None ) - XFixesDestroyRegion( display(), damage_region ); - damage_region = None; + damage_region = QRegion(); } #endif diff --git a/events.cpp b/events.cpp index b4c46c6205..969e9e8664 100644 --- a/events.cpp +++ b/events.cpp @@ -21,6 +21,8 @@ License. See the file "COPYING" for the exact licensing terms. #include "tabbox.h" #include "group.h" #include "rules.h" +#include "unmanaged.h" +#include "scene.h" #include #include @@ -262,6 +264,11 @@ bool Workspace::workspaceEvent( XEvent * e ) if( c->windowEvent( e )) return true; } + else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( e->xany.window ))) + { + if( c->windowEvent( e )) + return true; + } else { Window special = findSpecialEventWindow( e ); @@ -319,13 +326,8 @@ bool Workspace::workspaceEvent( XEvent * e ) } return true; } - return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt } - case MapNotify: - - return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt - case ReparentNotify: { //do not confuse Qt with these events. After all, _we_ are the @@ -375,6 +377,22 @@ bool Workspace::workspaceEvent( XEvent * e ) } break; } + case MapNotify: + { + if( e->xmap.override_redirect ) + { + Unmanaged* c = findUnmanaged( HandleMatchPredicate( e->xmap.window )); + if( c == NULL ) + c = createUnmanaged( e->xmap.window ); + if( c ) + { + c->windowEvent( e ); + return true; + } + } + return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt + } + case EnterNotify: { if ( QWhatsThis::inWhatsThisMode() ) @@ -455,6 +473,10 @@ bool Workspace::workspaceEvent( XEvent * e ) XRefreshKeyboardMapping( &e->xmapping ); tab_box->updateKeyMapping(); break; + case Expose: + if( e->xexpose.window == rootWindow() && compositing()) // root window needs repainting + addDamage( e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height ); + break; default: break; } @@ -551,6 +573,19 @@ bool Client::windowEvent( XEvent* e ) if( demandAttentionKNotifyTimer != NULL ) demandAttentionKNotify(); } + if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity ) + { + if( compositing()) + { + addDamage( rect()); + scene->windowOpacityChanged( this ); + } + else + { // forward to the frame if there's possibly another compositing manager running + NETWinInfo i( display(), frameId(), rootWindow(), 0 ); + i.setOpacity( info->opacity()); + } + } } // TODO move all focus handling stuff to separate file? @@ -636,13 +671,18 @@ bool Client::windowEvent( XEvent* e ) break; default: if( e->xany.window == window()) - { - if( e->type == Shape::shapeEvent() ) { - is_shape = Shape::hasShape( window()); // workaround for #19644 - updateShape(); + if( e->type == Extensions::shapeNotifyEvent() ) + { + is_shape = hasShape( window()); // workaround for #19644 + updateShape(); + } + } + if( e->xany.window == frameId()) + { + if( e->type == Extensions::damageNotifyEvent()) + damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e )); } - } break; } return true; // eat all events @@ -1562,6 +1602,57 @@ void Client::keyPressEvent( uint key_code ) QCursor::setPos( pos ); } +// **************************************** +// Unmanaged +// **************************************** + +bool Unmanaged::windowEvent( XEvent* e ) + { + unsigned long dirty[ 2 ]; + info->event( e, dirty, 2 ); // pass through the NET stuff + if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity ) + { + scene->windowOpacityChanged( this ); + addDamage( rect()); + } + switch (e->type) + { + case UnmapNotify: + unmapNotifyEvent( &e->xunmap ); + break; + case MapNotify: + mapNotifyEvent( &e->xmap ); + break; + case ConfigureNotify: + configureNotifyEvent( &e->xconfigure ); + break; + default: + if( e->type == Extensions::damageNotifyEvent()) + damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e )); + break; + } + return true; // eat all events + } + +void Unmanaged::mapNotifyEvent( XMapEvent* ) + { + } + +void Unmanaged::unmapNotifyEvent( XUnmapEvent* ) + { + release(); + } + +void Unmanaged::configureNotifyEvent( XConfigureEvent* e ) + { + resetWindowPixmap(); + // TODO add damage only if the window is not obscured + workspace()->addDamage( this, geometry()); + geom = QRect( e->x, e->y, e->width, e->height ); + // TODO maybe only damage changed area + addDamage( rect()); + } + // **************************************** // Group // **************************************** diff --git a/geometry.cpp b/geometry.cpp index b90b617efd..02595c9323 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "notifications.h" #include "geometrytip.h" #include "rules.h" +#include "effects.h" #include #include @@ -1657,9 +1658,11 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force ) { client_size = QSize( w - border_left - border_right, h - border_top - border_bottom ); } - if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h )) + if( force == NormalGeometrySet && geom == QRect( x, y, w, h )) return; - frame_geometry = QRect( x, y, w, h ); + // TODO add damage only if not obscured + workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry + geom = QRect( x, y, w, h ); updateWorkareaDiffs(); if( postpone_geometry_updates != 0 ) { @@ -1676,12 +1679,15 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force ) cs.width(), cs.height()); XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height()); } - updateShape(); + if( shape()) + updateShape(); // SELI TODO won't this be too expensive? updateWorkareaDiffs(); sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + resetWindowPixmap(); + addDamage( rect()); } void Client::plainResize( int w, int h, ForceGeometry_t force ) @@ -1711,9 +1717,10 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) kDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl; kDebug() << kBacktrace() << endl; } - if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h )) + if( force == NormalGeometrySet && geom.size() == QSize( w, h )) return; - frame_geometry.setSize( QSize( w, h )); + workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry + geom.setSize( QSize( w, h )); updateWorkareaDiffs(); if( postpone_geometry_updates != 0 ) { @@ -1730,11 +1737,15 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) cs.width(), cs.height()); XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height()); } - updateShape(); + if( shape()) + updateShape(); updateWorkareaDiffs(); sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + resetWindowPixmap(); + // TODO add damage only in added area? + addDamage( rect()); } /*! @@ -1742,9 +1753,10 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) */ void Client::move( int x, int y, ForceGeometry_t force ) { - if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y )) + if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y )) return; - frame_geometry.moveTopLeft( QPoint( x, y )); + workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry + geom.moveTopLeft( QPoint( x, y )); updateWorkareaDiffs(); if( postpone_geometry_updates != 0 ) { @@ -1755,9 +1767,10 @@ void Client::move( int x, int y, ForceGeometry_t force ) sendSyntheticConfigureNotify(); updateWindowRules(); checkMaximizeGeometry(); + // client itself is not damaged + workspace()->addDamage( this, geometry()); } - void Client::postponeGeometryUpdates( bool postpone ) { if( postpone ) @@ -2255,6 +2268,8 @@ bool Client::startMoveResize() // not needed anymore? kapp->installEventFilter( eater ); } Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart ); + if( effects ) + effects->windowUserMovedResized( this, true, false ); return true; } @@ -2268,6 +2283,8 @@ void Client::finishMoveResize( bool cancel ) checkMaximizeGeometry(); // FRAME update(); Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd ); + if( effects ) + effects->windowUserMovedResized( this, false, true ); } void Client::leaveMoveResize() @@ -2531,7 +2548,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root ) } if ( isMove() ) workspace()->clientMoved(globalPos, xTime()); + if( effects ) + effects->windowUserMovedResized( this, false, false ); } - } // namespace diff --git a/scene.cpp b/scene.cpp index 4229fa024a..96da1d6496 100644 --- a/scene.cpp +++ b/scene.cpp @@ -42,7 +42,7 @@ void Scene::windowDeleted( Toplevel* ) { } -void Scene::transformWindowDamage( Toplevel*, XserverRegion ) const +void Scene::transformWindowDamage( Toplevel*, QRegion& ) const { } diff --git a/scene.h b/scene.h index fdc9af563b..6b2eafcfac 100644 --- a/scene.h +++ b/scene.h @@ -23,12 +23,12 @@ class Scene public: Scene( Workspace* ws ); virtual ~Scene(); - virtual void paint( XserverRegion damage, ToplevelList windows ) = 0; + virtual void paint( QRegion damage, ToplevelList windows ) = 0; virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* ); virtual void windowAdded( Toplevel* ); virtual void windowDeleted( Toplevel* ); - virtual void transformWindowDamage( Toplevel*, XserverRegion ) const; + virtual void transformWindowDamage( Toplevel*, QRegion& ) const; virtual void updateTransformation( Toplevel* ); protected: Workspace* wspace; diff --git a/scene_basic.cpp b/scene_basic.cpp index 9962200ec9..c1dff73041 100644 --- a/scene_basic.cpp +++ b/scene_basic.cpp @@ -29,7 +29,7 @@ SceneBasic::~SceneBasic() { } -void SceneBasic::paint( XserverRegion, ToplevelList windows ) +void SceneBasic::paint( QRegion, ToplevelList windows ) { Pixmap composite_pixmap = XCreatePixmap( display(), rootWindow(), displayWidth(), displayHeight(), QX11Info::appDepth()); XGCValues val; diff --git a/scene_basic.h b/scene_basic.h index 2a8a04af4a..8c5756b64e 100644 --- a/scene_basic.h +++ b/scene_basic.h @@ -22,7 +22,7 @@ class SceneBasic public: SceneBasic( Workspace* ws ); virtual ~SceneBasic(); - virtual void paint( XserverRegion damage, ToplevelList windows ); + virtual void paint( QRegion damage, ToplevelList windows ); }; } // namespace diff --git a/scene_opengl.cpp b/scene_opengl.cpp index bd229d4c77..687c6b622c 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -114,7 +114,7 @@ static void quadDraw( int x, int y, int w, int h ) glVertex2i( x, y + h ); } -void SceneOpenGL::paint( XserverRegion, ToplevelList windows ) +void SceneOpenGL::paint( QRegion, ToplevelList windows ) { grabXServer(); glXWaitX(); diff --git a/scene_opengl.h b/scene_opengl.h index 7d3533ef20..cdf996c6a7 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -25,7 +25,7 @@ class SceneOpenGL public: SceneOpenGL( Workspace* ws ); virtual ~SceneOpenGL(); - virtual void paint( XserverRegion damage, ToplevelList windows ); + virtual void paint( QRegion damage, ToplevelList windows ); virtual void windowAdded( Toplevel* ); virtual void windowDeleted( Toplevel* ); private: diff --git a/scene_xrender.cpp b/scene_xrender.cpp index 3c76bca62e..dbfe4c2eef 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -22,6 +22,32 @@ namespace KWinInternal // SceneXrender //**************************************** +struct RegionDebug + { + RegionDebug( XserverRegion r ) : rr( r ) {} + XserverRegion rr; + }; + +#ifdef NDEBUG +inline +kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; } +#else +kdbgstream& operator<<( kdbgstream& stream, RegionDebug r ) + { + if( r.rr == None ) + return stream << "EMPTY"; + int num; + XRectangle* rects = XFixesFetchRegion( display(), r.rr, &num ); + if( rects == NULL || num == 0 ) + return stream << "EMPTY"; + for( int i = 0; + i < num; + ++i ) + stream << "[" << rects[ i ].x << "+" << rects[ i ].y << " " << rects[ i ].width << "x" << rects[ i ].height << "]"; + return stream; + } +#endif + SceneXrender::SceneXrender( Workspace* ws ) : Scene( ws ) { @@ -42,16 +68,24 @@ SceneXrender::~SceneXrender() (*it).free(); } -void SceneXrender::paint( XserverRegion damage, ToplevelList windows ) +void SceneXrender::paint( QRegion dam, ToplevelList windows ) { #if 1 - XRectangle r; - r.x = 0; - r.y = 0; - r.width = displayWidth(); - r.height = displayHeight(); - XFixesSetRegion( display(), damage, &r, 1 ); + dam = QRegion( 0, 0, displayWidth(), displayHeight()); #endif + QVector< QRect > rects = dam.rects(); + XRectangle* xr = new XRectangle[ rects.count() ]; + for( int i = 0; + i < rects.count(); + ++i ) + { + xr[ i ].x = rects[ i ].x(); + xr[ i ].y = rects[ i ].y(); + xr[ i ].width = rects[ i ].width(); + xr[ i ].height = rects[ i ].height(); + } + XserverRegion damage = XFixesCreateRegion( display(), xr, rects.count()); + delete[] xr; // Use the damage region as the clip region for the root window XFixesSetPictureClipRegion( display(), front, 0, 0, damage ); // Prepare pass for windows @@ -144,9 +178,10 @@ void SceneXrender::paint( XserverRegion damage, ToplevelList windows ) XFixesSetPictureClipRegion( display(), buffer, 0, 0, None ); XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight()); XFlush( display()); + XFixesDestroyRegion( display(), damage ); } -void SceneXrender::transformWindowDamage( Toplevel* c, XserverRegion r ) const +void SceneXrender::transformWindowDamage( Toplevel* c, QRegion& r ) const { if( !window_data.contains( c )) return; @@ -154,17 +189,13 @@ void SceneXrender::transformWindowDamage( Toplevel* c, XserverRegion r ) const if( matrix.isIdentity()) return; if( matrix.isOnlyTranslate()) - XFixesTranslateRegion( display(), r, int( matrix.xTranslate()), int( matrix.yTranslate())); + r.translate( int( matrix.xTranslate()), int( matrix.yTranslate())); else { // The region here should be translated using the matrix, but that's not possible // (well, maybe fetch the region and transform manually - TODO check). So simply // mark whole screen as damaged. - XRectangle s; - s.x = s.y = 0; - s.width = displayWidth(); - s.height = displayHeight(); - XFixesSetRegion( display(), r, &s, 1 ); + r = QRegion( 0, 0, displayWidth(), displayHeight()); } } diff --git a/scene_xrender.h b/scene_xrender.h index 281db07513..3b80e1fc4c 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -30,12 +30,12 @@ class SceneXrender public: SceneXrender( Workspace* ws ); virtual ~SceneXrender(); - virtual void paint( XserverRegion damage, ToplevelList windows ); + virtual void paint( QRegion damage, ToplevelList windows ); virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* ); virtual void windowAdded( Toplevel* ); virtual void windowDeleted( Toplevel* ); - virtual void transformWindowDamage( Toplevel*, XserverRegion ) const; + virtual void transformWindowDamage( Toplevel*, QRegion& ) const; virtual void updateTransformation( Toplevel* ); private: void createBuffer(); diff --git a/toplevel.cpp b/toplevel.cpp index da5a69256a..e3eb0ea9e1 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -18,7 +18,6 @@ Toplevel::Toplevel( Workspace* ws ) , id( None ) , wspace( ws ) , damage_handle( None ) - , damage_region( None ) , window_pixmap( None ) { } @@ -26,7 +25,6 @@ Toplevel::Toplevel( Workspace* ws ) Toplevel::~Toplevel() { assert( damage_handle == None ); - assert( damage_region == None ); assert( window_pixmap == None ); } diff --git a/toplevel.h b/toplevel.h index 8f453ac118..aad0d79037 100644 --- a/toplevel.h +++ b/toplevel.h @@ -60,8 +60,7 @@ class Toplevel void finishCompositing(); void addDamage( const QRect& r ); void addDamage( int x, int y, int w, int h ); - void addDamage( XserverRegion r, bool destroy ); - XserverRegion damage() const; + QRegion damage() const; void resetDamage(); protected: void setHandle( Window id ); @@ -75,7 +74,7 @@ class Toplevel Window id; Workspace* wspace; Damage damage_handle; - XserverRegion damage_region; + QRegion damage_region; mutable Pixmap window_pixmap; }; @@ -185,7 +184,7 @@ inline bool Toplevel::isNormalWindow() const return windowType() == NET::Normal; } -inline XserverRegion Toplevel::damage() const +inline QRegion Toplevel::damage() const { return damage_region; } diff --git a/utils.cpp b/utils.cpp index 65a1256b0c..8b0f12c485 100644 --- a/utils.cpp +++ b/utils.cpp @@ -30,6 +30,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include + #include #include "atoms.h" @@ -42,41 +43,54 @@ namespace KWinInternal #ifndef KCMRULES -// used to store the return values of -// XShapeQueryExtension. -// Necessary since shaped window are an extension to X -int Shape::kwin_shape_version = 0; -int Shape::kwin_shape_event = 0; +bool Extensions::has_shape = 0; +int Extensions::shape_event_base = 0; +bool Extensions::has_damage = 0; +int Extensions::damage_event_base = 0; +bool Extensions::has_composite = 0; +bool Extensions::has_fixes = 0; -// does the window w need a shape combine mask around it? -bool Shape::hasShape( WId w) +void Extensions::init() { - int xws, yws, xbs, ybs; - unsigned int wws, hws, wbs, hbs; - int boundingShaped = 0, clipShaped = 0; - if (!available()) - return false; - XShapeQueryExtents(display(), w, - &boundingShaped, &xws, &yws, &wws, &hws, - &clipShaped, &xbs, &ybs, &wbs, &hbs); - return boundingShaped != 0; - } - -int Shape::shapeEvent() - { - return kwin_shape_event; - } - -void Shape::init() - { - kwin_shape_version = 0; int dummy; - if( !XShapeQueryExtension( display(), &kwin_shape_event, &dummy )) - return; - int major, minor; - if( !XShapeQueryVersion( display(), &major, &minor )) - return; - kwin_shape_version = major * 0x10 + minor; + has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy); +#ifdef HAVE_XDAMAGE + has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy ); +#else + has_damage = false; +#endif +#ifdef HAVE_XCOMPOSITE + has_composite = XCompositeQueryExtension( display(), &dummy, &dummy ); + if( has_composite ) + { + int major = 0; + int minor = 2; + XCompositeQueryVersion( display(), &major, &minor ); + if( major == 0 && minor < 2 ) + has_composite = false; + } +#else + has_composite = false; +#endif +#ifdef HAVE_XFIXES + has_fixes = XFixesQueryExtension( display(), &dummy, &dummy ); +#else + has_fixes = false; +#endif + } + +int Extensions::shapeNotifyEvent() + { + return shape_event_base + ShapeNotify; + } + +int Extensions::damageNotifyEvent() + { +#ifdef HAVE_XDAMAGE + return damage_event_base + XDamageNotify; +#else + return 0; +#endif } void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move, @@ -300,7 +314,6 @@ bool grabbedXServer() { return server_grab_count > 0; } - #endif bool isLocalMachine( const QByteArray& host ) @@ -367,8 +380,6 @@ void ShortcutDialog::accept() KShortcutDialog::accept(); } #endif - - } // namespace #ifndef KCMRULES diff --git a/utils.h b/utils.h index 6d76d83657..cd1247f54f 100644 --- a/utils.h +++ b/utils.h @@ -44,11 +44,6 @@ struct XDamageNotifyEvent { }; #endif -#ifndef HAVE_XFIXES -struct XserverRegion - { - }; -#endif const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask @@ -122,19 +117,6 @@ enum allowed_t { Allowed }; enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet }; -struct RegionDebug - { - RegionDebug( XserverRegion r ) : rr( r ) {} - XserverRegion rr; - }; - -#ifdef NDEBUG -inline -kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; } -#else -kdbgstream& operator<<( kdbgstream& stream, RegionDebug r ); -#endif - // Areas, mostly related to Xinerama enum clientAreaOption { diff --git a/workspace.h b/workspace.h index bc6e72b1a2..33275a122e 100644 --- a/workspace.h +++ b/workspace.h @@ -285,10 +285,10 @@ class Workspace : public QObject, public KDecorationDefines void addDamage( const QRect& r ); void addDamage( int x, int y, int w, int h ); - void addDamage( XserverRegion r, bool destroy ); + // these damage the workspace without actually damaging the contents + // of the toplevel - e.g. when the toplevel moves away from that area void addDamage( Toplevel* c, const QRect& r ); void addDamage( Toplevel* c, int x, int y, int w, int h ); - void addDamage( Toplevel* c, XserverRegion r, bool destroy ); public slots: void refresh(); @@ -633,7 +633,7 @@ class Workspace : public QObject, public KDecorationDefines bool forced_global_mouse_grab; friend class StackingUpdatesBlocker; QTimer compositeTimer; - XserverRegion damage_region; + QRegion damage_region; QSlider *transSlider; QPushButton *transButton; };