diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cea5eba95..29cc3099bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(kwin_KDEINIT_SRCS effects/boxswitch.cpp effects/fallapart.cpp effects/drunken.cpp + effects/demo_taskbarthumbnail.cpp effects/flame.cpp effects/shadow.cpp effects/test_input.cpp diff --git a/effects.cpp b/effects.cpp index 695ff98a1d..90a251c1b1 100644 --- a/effects.cpp +++ b/effects.cpp @@ -16,6 +16,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "options.h" #include "effects/boxswitch.h" +#include "effects/demo_taskbarthumbnail.h" #include "effects/desktopchangeslide.h" #include "effects/dialogparent.h" #include "effects/drunken.h" @@ -207,6 +208,7 @@ EffectsHandler::EffectsHandler() registerEffect("DesktopChangeSlide", new GenericEffectFactory); registerEffect("BoxSwitch", new GenericEffectFactory); registerEffect("Drunken", new GenericEffectFactory); + registerEffect("TaskbarThumbnail", new GenericEffectFactory); registerEffect("Shadow", new GenericEffectFactory); registerEffect("TestInput", new GenericEffectFactory); diff --git a/effects/demo_taskbarthumbnail.cpp b/effects/demo_taskbarthumbnail.cpp new file mode 100644 index 0000000000..54ce7a40de --- /dev/null +++ b/effects/demo_taskbarthumbnail.cpp @@ -0,0 +1,115 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + + +#include "demo_taskbarthumbnail.h" + +#include +#include + + +// Note that currently effects need to be manually enabled in the EffectsHandler +// class constructor (in effects.cpp). + +namespace KWinInternal +{ + +TaskbarThumbnailEffect::TaskbarThumbnailEffect() + { + mLastCursorPos = QPoint(-1, -1); + } + + +void TaskbarThumbnailEffect::prePaintScreen( int* mask, QRegion* region, int time ) + { + // We might need to paint thumbnails if cursor has moved since last + // painting or some thumbnails were painted the last time + QPoint cpos = cursorPos(); + if(cpos != mLastCursorPos || mThumbnails.count() > 0) + { + *mask |= Scene::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + mThumbnails.clear(); + mLastCursorPos = cpos; + } + + effects->prePaintScreen(mask, region, time); + } + +void TaskbarThumbnailEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) + { + Client* c = dynamic_cast< Client* >( w->window() ); + if( c ) + { + QRect iconGeo = c->iconGeometry(); + if(iconGeo.contains( mLastCursorPos )) + { + mThumbnails.append( w ); + } + } + + effects->prePaintWindow( w, mask, paint, clip, time ); + } + +void TaskbarThumbnailEffect::postPaintScreen() + { + // Paint the thumbnails. They need to be painted after other windows + // because we want them on top of everything else + int space = 4; + foreach( EffectWindow* w, mThumbnails ) + { + Client* c = static_cast< Client* >( w->window() ); + QRect thumb = getThumbnailPosition(c, &space); + WindowPaintData thumbdata; + thumbdata.xTranslate = thumb.x() - c->x(); + thumbdata.yTranslate = thumb.y() - c->y(); + thumbdata.xScale = thumb.width() / (float)c->width(); + thumbdata.yScale = thumb.height() / (float)c->height(); + // From Scene::Window::infiniteRegion() + QRegion infRegion = QRegion( INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX ); + effects->paintWindow( w, Scene::PAINT_WINDOW_TRANSFORMED, infRegion, thumbdata ); + } + + // Call the next effect. + effects->postPaintScreen(); + } + +QRect TaskbarThumbnailEffect::getThumbnailPosition( Client* c, int* space ) const + { + QRect thumb; + QRect icon = c->iconGeometry(); + + // Try to figure out if taskbar is horizontal or vertical + if( icon.right() < 40 || ( displayWidth() - icon.left()) < 40 ) + { + // Vertical taskbar... + float scale = qMin(qMax(icon.height(), 100) / (float)c->height(), 200.0f / c->width()); + thumb.setSize( QSize( int(scale * c->width()),int(scale * c->height()) )); + if( icon.right() < 40 ) // ...on the left + thumb.moveTopLeft( QPoint( icon.right() + *space, icon.top() )); + else // ...on the right + thumb.moveTopRight( QPoint( icon.left() - *space, icon.top())); + *space += thumb.width() + 8; + } + else + { + // Horizontal taskbar... + float scale = qMin(qMax(icon.width(), 75) / (float)c->width(), 200.0f / c->height()); + thumb.setSize( QSize( int(scale * c->width()),int(scale * c->height()) )); + if( icon.top() < ( displayHeight() - icon.bottom())) // ...at the top + thumb.moveTopLeft( QPoint( icon.left(), icon.bottom() + *space )); + else // ...at the bottom + thumb.moveBottomLeft( QPoint( icon.left(), icon.top() - *space )); + *space += thumb.height() + 8; + } + return thumb; + } + +} // namespace + diff --git a/effects/demo_taskbarthumbnail.h b/effects/demo_taskbarthumbnail.h new file mode 100644 index 0000000000..5270bee48a --- /dev/null +++ b/effects/demo_taskbarthumbnail.h @@ -0,0 +1,49 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_TASKBARTHUMBNAIL_H +#define KWIN_TASKBARTHUMBNAIL_H + +// Include with base class for effects. +#include + + +namespace KWinInternal +{ + +/** + * Render small thumbnail of window next to it's taskbar entry when the cursor + * is above the taskbar entry. + * Note that this functionality will be replaced in the future so that taskbar + * itself can request a thumbnail to be rendered in a give location with a + * given size. + **/ +class TaskbarThumbnailEffect + : public Effect + { + public: + TaskbarThumbnailEffect(); + + virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void postPaintScreen(); + + + protected: + QRect getThumbnailPosition( Client*c, int* space ) const; + + private: + QList< EffectWindow* > mThumbnails; + QPoint mLastCursorPos; + }; + +} // namespace + +#endif