From ef79d4c44320e8950c291122324fb40c94accce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 26 Jul 2010 20:00:04 +0000 Subject: [PATCH] Use the normal Plasma selection to highlight the selected window in boxswitch. So it is more consistent (in KDE newspeak "elegant") with other selections and as a plus we get rid of all the custom rendering code in boxswitch. svn path=/trunk/KDE/kdebase/workspace/; revision=1155051 --- effects.cpp | 19 +++++++++++++++ effects.h | 11 +++++++++ effects/boxswitch/boxswitch.cpp | 43 ++++----------------------------- effects/boxswitch/boxswitch.h | 1 - lib/kwineffects.h | 10 +++++++- scene.h | 1 + scene_opengl.cpp | 24 ++++++++++++++++++ scene_opengl.h | 2 ++ scene_xrender.cpp | 21 ++++++++++++++++ scene_xrender.h | 2 ++ 10 files changed, 94 insertions(+), 40 deletions(-) diff --git a/effects.cpp b/effects.cpp index 3bbb687f94..1114e37afa 100644 --- a/effects.cpp +++ b/effects.cpp @@ -1668,6 +1668,10 @@ EffectFrameImpl::EffectFrameImpl( EffectFrameStyle style, bool staticSize, QPoin { m_frame.setImagePath( "widgets/background" ); m_frame.setCacheAllRenderedFrames( true ); + m_selection.setImagePath( "widgets/viewitem" ); + m_selection.setElementPrefix( "hover" ); + m_selection.setCacheAllRenderedFrames( true ); + m_selection.setEnabledBorders( Plasma::FrameSvg::AllBorders ); connect( Plasma::Theme::defaultTheme(), SIGNAL( themeChanged() ), this, SLOT( plasmaThemeChanged() )); } @@ -1843,6 +1847,21 @@ void EffectFrameImpl::setText( const QString& text ) } } +void EffectFrameImpl::setSelection( const QRect& selection ) + { + if( selection == m_selectionGeometry ) + { + return; + } + m_selectionGeometry = selection; + if( m_selectionGeometry.size() != m_selection.frameSize().toSize() ) + { + m_selection.resizeFrame( m_selectionGeometry.size() ); + } + // TODO; optimize to only recreate when resizing + m_sceneFrame->freeSelection(); + } + void EffectFrameImpl::autoResize() { if( m_static ) diff --git a/effects.h b/effects.h index de21c0738d..2378611ae6 100644 --- a/effects.h +++ b/effects.h @@ -356,6 +356,15 @@ class EffectFrameImpl { return m_shader; } + virtual void setSelection( const QRect& selection ); + const QRect& selection() const + { + return m_selectionGeometry; + } + Plasma::FrameSvg& selectionFrame() + { + return m_selection; + } private Q_SLOTS: void plasmaThemeChanged(); @@ -367,6 +376,7 @@ class EffectFrameImpl EffectFrameStyle m_style; Plasma::FrameSvg m_frame; // TODO: share between all EffectFrames + Plasma::FrameSvg m_selection; // Position bool m_static; @@ -379,6 +389,7 @@ class EffectFrameImpl QFont m_font; QPixmap m_icon; QSize m_iconSize; + QRect m_selectionGeometry; Scene::EffectFrame* m_sceneFrame; GLShader* m_shader; diff --git a/effects/boxswitch/boxswitch.cpp b/effects/boxswitch/boxswitch.cpp index de89568eb9..ef0f17d052 100644 --- a/effects/boxswitch/boxswitch.cpp +++ b/effects/boxswitch/boxswitch.cpp @@ -151,15 +151,13 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da { if( !painting_desktop ) { + thumbnailFrame->setSelection( desktops[ selected_desktop ]->area ); thumbnailFrame->render( region ); QHash< int, ItemInfo* >::const_iterator i; for( i = desktops.constBegin(); i != desktops.constEnd(); ++i ) { painting_desktop = i.key(); - if( painting_desktop == selected_desktop ) - paintHighlight( desktops[ painting_desktop ]->area ); //effects->desktopName( painting_desktop ) - paintDesktopThumbnail( painting_desktop ); } painting_desktop = 0; @@ -170,13 +168,16 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da void BoxSwitchEffect::paintWindowsBox(const QRegion& region) { + if( (mAnimateSwitch && !mProxyActivated) || (mProxyActivated && mProxyAnimateSwitch) ) + thumbnailFrame->setSelection( highlight_area ); + else + thumbnailFrame->setSelection( windows[ selected_window ]->area ); thumbnailFrame->render( region ); if( (mAnimateSwitch && !mProxyActivated) || (mProxyActivated && mProxyAnimateSwitch) ) { // HACK: PaintClipper is used because window split is somehow wrong if the height is greater than width PaintClipper::push( frame_area ); - paintHighlight( highlight_area ); QHash< EffectWindow*, ItemInfo* >::const_iterator i; for( i = windows.constBegin(); i != windows.constEnd(); ++i ) { @@ -190,8 +191,6 @@ void BoxSwitchEffect::paintWindowsBox(const QRegion& region) QHash< EffectWindow*, ItemInfo* >::const_iterator i; for( i = windows.constBegin(); i != windows.constEnd(); ++i ) { - if( i.key() == selected_window ) - paintHighlight( i.value()->area ); paintWindowThumbnail( i.key() ); paintWindowIcon( i.key() ); } @@ -764,38 +763,6 @@ void BoxSwitchEffect::calculateItemSizes() } } -void BoxSwitchEffect::paintHighlight( QRect area ) - { -#ifdef KWIN_HAVE_OPENGL_COMPOSITING - if( effects->compositingType() == OpenGLCompositing ) - { - glPushAttrib( GL_CURRENT_BIT ); - glColor4f( color_highlight.redF(), color_highlight.greenF(), color_highlight.blueF(), color_highlight.alphaF()); - renderRoundBox( area, 6 ); - glPopAttrib(); - } -#endif -#ifdef KWIN_HAVE_XRENDER_COMPOSITING - if( effects->compositingType() == XRenderCompositing ) - { - Pixmap pixmap = XCreatePixmap( display(), rootWindow(), - area.width(), area.height(), 32 ); - XRenderPicture pic( pixmap, 32 ); - XFreePixmap( display(), pixmap ); - XRenderColor col; - col.alpha = int( color_highlight.alphaF() * 0xffff ); - col.red = int( color_highlight.redF() * color_highlight.alphaF() * 0xffff ); - col.green = int( color_highlight.greenF() * color_highlight.alphaF() * 0xffff ); - col.blue = int( color_highlight.blueF() * color_highlight.alphaF() * 0xffff ); - XRenderFillRectangle( display(), PictOpSrc, pic, &col, 0, 0, - area.width(), area.height()); - XRenderComposite( display(), color_highlight.alphaF() != 1.0 ? PictOpOver : PictOpSrc, - pic, None, effects->xrenderBufferPicture(), - 0, 0, 0, 0, area.x(), area.y(), area.width(), area.height()); - } -#endif - } - void BoxSwitchEffect::paintWindowThumbnail( EffectWindow* w ) { if( !windows.contains( w )) diff --git a/effects/boxswitch/boxswitch.h b/effects/boxswitch/boxswitch.h index 7a80daad68..df214da1c6 100644 --- a/effects/boxswitch/boxswitch.h +++ b/effects/boxswitch/boxswitch.h @@ -70,7 +70,6 @@ class BoxSwitchEffect void calculateItemSizes(); void setSelectedWindow( EffectWindow* w ); - void paintHighlight( QRect area ); void paintWindowThumbnail( EffectWindow* w ); void paintDesktopThumbnail( int iDesktop ); void paintWindowIcon( EffectWindow* w ); diff --git a/lib/kwineffects.h b/lib/kwineffects.h index f816546c13..2720844e73 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -170,7 +170,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 154 +#define KWIN_EFFECT_API_VERSION_MINOR 155 #define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \ KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR ) @@ -1737,6 +1737,14 @@ class KWIN_EXPORT EffectFrame virtual void setIconSize( const QSize& size ) = 0; virtual const QSize& iconSize() const = 0; + /** + * Sets the geometry of a selection. + * To remove the selection set a null rect. + * This is only available if the an styled EffectFrame is used. + * @param selection The geometry of the selection in screen coordinates. + **/ + virtual void setSelection( const QRect& selection ) = 0; + /** * @param shader The GLShader for rendering. **/ diff --git a/scene.h b/scene.h index b302fbc7ce..0d2754ee0e 100644 --- a/scene.h +++ b/scene.h @@ -223,6 +223,7 @@ class Scene::EffectFrame virtual void free() = 0; virtual void freeIconFrame() = 0; virtual void freeTextFrame() = 0; + virtual void freeSelection() = 0; protected: EffectFrameImpl* m_effectFrame; diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 7af4440da9..a98ea30919 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -1921,6 +1921,7 @@ SceneOpenGL::EffectFrame::EffectFrame( EffectFrameImpl* frame ) , m_texture( NULL ) , m_textTexture( NULL ) , m_iconTexture( NULL ) + , m_selectionTexture( NULL ) , m_unstyledVBO( NULL ) { if( m_effectFrame->style() == Unstyled && !m_unstyledTexture ) @@ -1934,6 +1935,7 @@ SceneOpenGL::EffectFrame::~EffectFrame() delete m_texture; delete m_textTexture; delete m_iconTexture; + delete m_selectionTexture; delete m_unstyledVBO; } @@ -1945,6 +1947,8 @@ void SceneOpenGL::EffectFrame::free() m_textTexture = NULL; delete m_iconTexture; m_iconTexture = NULL; + delete m_selectionTexture; + m_selectionTexture = NULL; delete m_unstyledVBO; m_unstyledVBO = NULL; } @@ -1961,6 +1965,12 @@ void SceneOpenGL::EffectFrame::freeTextFrame() m_textTexture = NULL; } +void SceneOpenGL::EffectFrame::freeSelection() + { + delete m_selectionTexture; + m_selectionTexture = NULL; + } + void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double frameOpacity ) { if( m_effectFrame->geometry().isEmpty() ) @@ -2118,6 +2128,20 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr m_effectFrame->frame().getMargins( left, top, right, bottom ); // m_geometry is the inner geometry m_texture->render( region, m_effectFrame->geometry().adjusted( -left, -top, right, bottom )); m_texture->unbind(); + + if( !m_effectFrame->selection().isNull() ) + { + if( !m_selectionTexture ) // Lazy creation + { + QPixmap pixmap = m_effectFrame->selectionFrame().framePixmap(); + m_selectionTexture = new Texture( pixmap.handle(), pixmap.size(), pixmap.depth() ); + } + glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); + m_selectionTexture->bind(); + m_selectionTexture->render( region, m_effectFrame->selection() ); + m_selectionTexture->unbind(); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } } if( shader ) diff --git a/scene_opengl.h b/scene_opengl.h index 44abd7f33c..d429b1804d 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -176,6 +176,7 @@ class SceneOpenGL::EffectFrame virtual void free(); virtual void freeIconFrame(); virtual void freeTextFrame(); + virtual void freeSelection(); virtual void render(QRegion region, double opacity, double frameOpacity); @@ -188,6 +189,7 @@ class SceneOpenGL::EffectFrame GLTexture* m_texture; GLTexture* m_textTexture; GLTexture* m_iconTexture; + GLTexture* m_selectionTexture; GLVertexBuffer* m_unstyledVBO; static GLTexture* m_unstyledTexture; diff --git a/scene_xrender.cpp b/scene_xrender.cpp index c998ccfe81..28b474b996 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -855,6 +855,7 @@ SceneXrender::EffectFrame::EffectFrame( EffectFrameImpl* frame ) m_picture = NULL; m_textPicture = NULL; m_iconPicture = NULL; + m_selectionPicture = NULL; } SceneXrender::EffectFrame::~EffectFrame() @@ -862,6 +863,7 @@ SceneXrender::EffectFrame::~EffectFrame() delete m_picture; delete m_textPicture; delete m_iconPicture; + delete m_selectionPicture; } void SceneXrender::EffectFrame::free() @@ -872,6 +874,8 @@ void SceneXrender::EffectFrame::free() m_textPicture = NULL; delete m_iconPicture; m_iconPicture = NULL; + delete m_selectionPicture; + m_selectionPicture = NULL; } void SceneXrender::EffectFrame::freeIconFrame() @@ -886,6 +890,12 @@ void SceneXrender::EffectFrame::freeTextFrame() m_textPicture = NULL; } +void SceneXrender::EffectFrame::freeSelection() + { + delete m_selectionPicture; + m_selectionPicture = NULL; + } + void SceneXrender::EffectFrame::render( QRegion region, double opacity, double frameOpacity ) { if( m_effectFrame->geometry().isEmpty() ) @@ -908,6 +918,17 @@ void SceneXrender::EffectFrame::render( QRegion region, double opacity, double f QRect geom = m_effectFrame->geometry().adjusted( -left, -top, right, bottom ); XRenderComposite( display(), PictOpOver, *m_picture, None, effects->xrenderBufferPicture(), 0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() ); + + if( !m_effectFrame->selection().isNull() ) + { + if( !m_selectionPicture ) // Lazy creation + { + m_selectionPicture = new XRenderPicture( m_effectFrame->selectionFrame().framePixmap() ); + } + geom = m_effectFrame->selection(); + XRenderComposite( display(), PictOpOver, *m_selectionPicture, None, effects->xrenderBufferPicture(), + 0, 0, 0, 0, geom.x(), geom.y(), geom.width(), geom.height() ); + } } XRenderPicture fill = xRenderBlendPicture(opacity); diff --git a/scene_xrender.h b/scene_xrender.h index fa07462504..c2280493ee 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -103,6 +103,7 @@ class SceneXrender::EffectFrame virtual void free(); virtual void freeIconFrame(); virtual void freeTextFrame(); + virtual void freeSelection(); virtual void render( QRegion region, double opacity, double frameOpacity ); private: @@ -112,6 +113,7 @@ class SceneXrender::EffectFrame XRenderPicture* m_picture; XRenderPicture* m_textPicture; XRenderPicture* m_iconPicture; + XRenderPicture* m_selectionPicture; }; inline