diff --git a/client.h b/client.h index c80e5a7087..927bacadcc 100644 --- a/client.h +++ b/client.h @@ -85,8 +85,8 @@ class Client QSize minSize() const; QSize maxSize() const; - QPoint clientPos() const; // inside of geometry() - QSize clientSize() const; + virtual QPoint clientPos() const; // inside of geometry() + virtual QSize clientSize() const; bool windowEvent( XEvent* e ); virtual bool eventFilter( QObject* o, QEvent* e ); diff --git a/deleted.cpp b/deleted.cpp index 08c1142f67..e5758aedaa 100644 --- a/deleted.cpp +++ b/deleted.cpp @@ -43,6 +43,7 @@ void Deleted::copyToDeleted( Toplevel* c ) assert( dynamic_cast< Deleted* >( c ) == NULL ); Toplevel::copyToDeleted( c ); desk = c->desktop(); + contentsRect = QRect( c->clientPos(), c->clientSize()); if( WinInfo* cinfo = dynamic_cast< WinInfo* >( info )) cinfo->disable(); } @@ -64,6 +65,16 @@ int Deleted::desktop() const return desk; } +QPoint Deleted::clientPos() const + { + return contentsRect.topLeft(); + } + +QSize Deleted::clientSize() const + { + return contentsRect.size(); + } + void Deleted::debug( kdbgstream& stream ) const { stream << "\'ID:" << window() << "\' (deleted)"; diff --git a/deleted.h b/deleted.h index d8a3bba78a..269aef86ab 100644 --- a/deleted.h +++ b/deleted.h @@ -26,6 +26,8 @@ class Deleted void refWindow(); void unrefWindow( bool delay = false ); virtual int desktop() const; + virtual QPoint clientPos() const; + virtual QSize clientSize() const; protected: virtual void debug( kdbgstream& stream ) const; private: @@ -35,6 +37,7 @@ class Deleted int delete_refcount; double window_opacity; int desk; + QRect contentsRect; // for clientPos()/clientSize() }; inline void Deleted::refWindow() diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index 8e5aacc628..b6aa09e35a 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -437,6 +437,24 @@ void WindowQuadList::makeArrays( float** vertices, float** texcoords ) } } +WindowQuadList WindowQuadList::filterOut( WindowQuadType type ) const + { + foreach( WindowQuad q, *this ) + { + if( q.type == type ) // something to filter out, make a copy and filter + { + WindowQuadList ret; + foreach( WindowQuad q, *this ) + { + if( q.type != type ) + ret.append( q ); + } + return ret; + } + } + return *this; // nothing to filter out + } + bool WindowQuadList::smoothNeeded() const { return false; // TODO diff --git a/lib/kwineffects.h b/lib/kwineffects.h index 519781cb72..9e7a00f307 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -373,6 +373,13 @@ class KWIN_EXPORT WindowVertex float tx, ty; // texture coords }; +enum WindowQuadType + { + WindowQuadError, // for the stupid default ctor + WindowQuadContents, + WindowQuadDecoration, + }; + /** * @short Class representing one area of a window. * WindowQuads consists of four WindowVertex objects and represents one part of a window. @@ -380,10 +387,11 @@ class KWIN_EXPORT WindowVertex class KWIN_EXPORT WindowQuad { public: - WindowQuad(); + explicit WindowQuad( WindowQuadType type ); WindowQuad makeSubQuad( float x1, float y1, float x2, float y2 ) const; WindowVertex& operator[]( int index ); const WindowVertex& operator[]( int index ) const; + bool decoration() const; // these 8 work only with untransformed quads float left() const; float right() const; @@ -394,8 +402,10 @@ class KWIN_EXPORT WindowQuad float textureTop() const; float textureBottom() const; private: + friend class WindowQuadList; void checkUntransformed() const; WindowVertex verts[ 4 ]; + WindowQuadType type; // 0 - contents, 1 - decoration }; class KWIN_EXPORT WindowQuadList @@ -405,6 +415,7 @@ class KWIN_EXPORT WindowQuadList WindowQuadList splitAtX( float x ) const; WindowQuadList splitAtY( float y ) const; WindowQuadList makeGrid( int maxquadsize ) const; + WindowQuadList filterOut( WindowQuadType type ) const; bool smoothNeeded() const; void makeArrays( float** vertices, float** texcoords ); }; @@ -529,7 +540,8 @@ float WindowVertex::textureY() const ***************************************************************/ inline -WindowQuad::WindowQuad() +WindowQuad::WindowQuad( WindowQuadType t ) + : type( t ) { } @@ -547,6 +559,13 @@ const WindowVertex& WindowQuad::operator[]( int index ) const return verts[ index ]; } +inline +bool WindowQuad::decoration() const + { + assert( type != WindowQuadError ); + return type == WindowQuadDecoration; + } + inline void WindowQuad::checkUntransformed() const { diff --git a/scene.cpp b/scene.cpp index 876e686a9c..28be2eb1c1 100644 --- a/scene.cpp +++ b/scene.cpp @@ -175,7 +175,7 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData ) w->resetPaintingEnabled(); data.paint = infiniteRegion(); // no clipping, so doesn't really matter data.clip = QRegion(); - data.quads = buildQuads( w ); + data.quads = w->buildQuads(); // preparation step effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) @@ -211,7 +211,7 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region ) w->resetPaintingEnabled(); data.paint = region; data.clip = w->isOpaque() ? w->shape().translated( w->x(), w->y()) : QRegion(); - data.quads = buildQuads( w ); + data.quads = w->buildQuads(); // preparation step effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) @@ -276,22 +276,6 @@ void Scene::finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, Wind w->sceneWindow()->performPaint( mask, region, data ); } -WindowQuadList Scene::buildQuads( const Window* w ) - { - WindowQuadList ret; - foreach( QRect r, w->shape().rects()) - { - WindowQuad quad; - // TODO asi mam spatne pravy dolni roh - bud tady, nebo v jinych castech - quad[ 0 ] = WindowVertex( r.x(), r.y(), r.x(), r.y()); - quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), r.x() + r.width(), r.y()); - quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height()); - quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), r.x(), r.y() + r.height()); - ret.append( quad ); - } - return ret; - } - //**************************************** // Scene::Window //**************************************** @@ -396,4 +380,31 @@ void Scene::Window::disablePainting( int reason ) disable_painting |= reason; } +WindowQuadList Scene::Window::buildQuads() const + { + if( toplevel->clientPos() == QPoint( 0, 0 ) && toplevel->clientSize() == toplevel->size()) + return makeQuads( WindowQuadContents, shape()); // has no decoration + QRegion contents = shape() & QRect( toplevel->clientPos(), toplevel->clientSize()); + QRegion decoration = shape() - contents; + WindowQuadList ret = makeQuads( WindowQuadContents, contents ); + ret += makeQuads( WindowQuadDecoration, decoration ); + return ret; + } + +WindowQuadList Scene::Window::makeQuads( WindowQuadType type, const QRegion& reg ) const + { + WindowQuadList ret; + foreach( QRect r, reg.rects()) + { + WindowQuad quad( type ); + // TODO asi mam spatne pravy dolni roh - bud tady, nebo v jinych castech + quad[ 0 ] = WindowVertex( r.x(), r.y(), r.x(), r.y()); + quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), r.x() + r.width(), r.y()); + quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height()); + quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), r.x(), r.y() + r.height()); + ret.append( quad ); + } + return ret; + } + } // namespace diff --git a/scene.h b/scene.h index 94c7df3ad2..b0b5f1d133 100644 --- a/scene.h +++ b/scene.h @@ -95,8 +95,6 @@ class Scene virtual void paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads ); // called after all effects had their drawWindow() called void finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data ); - // creates initial quad list for a window - virtual WindowQuadList buildQuads( const Window* w ); // infinite region, i.e. everything static QRegion infiniteRegion(); // compute time since the last repaint @@ -173,7 +171,10 @@ class Scene::Window QRegion shape() const; void discardShape(); void updateToplevel( Toplevel* c ); + // creates initial quad list for the window + virtual WindowQuadList buildQuads() const; protected: + WindowQuadList makeQuads( WindowQuadType type, const QRegion& reg ) const; Toplevel* toplevel; ImageFilterType filter; private: diff --git a/scene_xrender.cpp b/scene_xrender.cpp index d4e0b59268..11c2582a35 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -211,7 +211,7 @@ void SceneXrender::paintTransformedScreen( int orig_mask ) data.paint = region; // TODO this is wrong, transformedShape() should be used here, but is not known yet data.clip = w->isOpaque() ? region : QRegion(); - data.quads = buildQuads( w ); + data.quads = w->buildQuads(); // preparation step effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) diff --git a/toplevel.h b/toplevel.h index 4a93907af4..b8cf559804 100644 --- a/toplevel.h +++ b/toplevel.h @@ -49,6 +49,8 @@ class Toplevel int y() const; int width() const; int height() const; + virtual QPoint clientPos() const = 0; // inside of geometry() + virtual QSize clientSize() const = 0; // prefer isXXX() instead NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const; diff --git a/unmanaged.cpp b/unmanaged.cpp index e9d555d45a..dc8a80900f 100644 --- a/unmanaged.cpp +++ b/unmanaged.cpp @@ -96,6 +96,16 @@ int Unmanaged::desktop() const return NET::OnAllDesktops; // TODO for some window types should be the current desktop? } +QPoint Unmanaged::clientPos() const + { + return QPoint( 0, 0 ); // unmanaged windows don't have decorations + } + +QSize Unmanaged::clientSize() const + { + return size(); + } + void Unmanaged::debug( kdbgstream& stream ) const { stream << "\'ID:" << window() << "\'"; diff --git a/unmanaged.h b/unmanaged.h index 938de0c3cf..b291f254ae 100644 --- a/unmanaged.h +++ b/unmanaged.h @@ -29,6 +29,8 @@ class Unmanaged bool track( Window w ); static void deleteUnmanaged( Unmanaged* c, allowed_t ); virtual int desktop() const; + virtual QPoint clientPos() const; + virtual QSize clientSize() const; protected: virtual void debug( kdbgstream& stream ) const; private: