diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24785cd6fa..b9db906bac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -109,6 +109,7 @@ set(kwin_KDEINIT_SRCS
scene_basic.cpp
scene_xrender.cpp
scene_opengl.cpp
+ thumbnailitem.cpp
lanczosfilter.cpp
deleted.cpp
effects.cpp
@@ -254,6 +255,7 @@ install( FILES
tabbox/qml/small_icons.qml
tabbox/qml/tabbox.qml
tabbox/qml/text.qml
+ tabbox/qml/thumbnails.qml
tabbox/qml/IconTabBox.qml
DESTINATION ${DATA_INSTALL_DIR}/kwin/tabbox )
diff --git a/effects.cpp b/effects.cpp
index c77c0e4793..000e35c911 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -30,6 +30,7 @@ along with this program. If not, see .
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
+#include "thumbnailitem.h"
#include "workspace.h"
#include "kwinglutils.h"
@@ -1278,7 +1279,9 @@ void EffectsHandlerImpl::slotHideOutline()
// EffectWindowImpl
//****************************************
-EffectWindowImpl::EffectWindowImpl() : EffectWindow()
+EffectWindowImpl::EffectWindowImpl()
+ : QObject(NULL)
+ , EffectWindow()
, toplevel(NULL)
, sw(NULL)
{
@@ -1743,6 +1746,36 @@ EffectWindow* effectWindow(Scene::Window* w)
return ret;
}
+void EffectWindowImpl::registerThumbnail(ThumbnailItem *item)
+{
+ insertThumbnail(item);
+ connect(item, SIGNAL(destroyed(QObject*)), SLOT(thumbnailDestroyed(QObject*)));
+ connect(item, SIGNAL(wIdChanged(qulonglong)), SLOT(thumbnailTargetChanged()));
+}
+
+void EffectWindowImpl::thumbnailDestroyed(QObject *object)
+{
+ // we know it is a ThumbnailItem
+ m_thumbnails.remove(static_cast(object));
+}
+
+void EffectWindowImpl::thumbnailTargetChanged()
+{
+ if (ThumbnailItem *item = qobject_cast(sender())) {
+ insertThumbnail(item);
+ }
+}
+
+void EffectWindowImpl::insertThumbnail(ThumbnailItem *item)
+{
+ EffectWindow *w = effects->findWindow(item->wId());
+ if (w) {
+ m_thumbnails.insert(item, QWeakPointer(static_cast(w)));
+ } else {
+ m_thumbnails.insert(item, QWeakPointer());
+ }
+}
+
//****************************************
// EffectWindowGroupImpl
//****************************************
diff --git a/effects.h b/effects.h
index 08a3996e83..6530871e8e 100644
--- a/effects.h
+++ b/effects.h
@@ -37,6 +37,8 @@ class KService;
namespace KWin
{
+class ThumbnailItem;
+
class Client;
class Deleted;
class Unmanaged;
@@ -218,8 +220,9 @@ private:
QList< Effect* >::iterator m_currentBuildQuadsIterator;
};
-class EffectWindowImpl : public EffectWindow
+class EffectWindowImpl : public QObject, public EffectWindow
{
+ Q_OBJECT
public:
EffectWindowImpl();
virtual ~EffectWindowImpl();
@@ -315,10 +318,20 @@ public:
void setData(int role, const QVariant &data);
QVariant data(int role) const;
+
+ void registerThumbnail(ThumbnailItem *item);
+ QHash > const &thumbnails() const {
+ return m_thumbnails;
+ }
+private Q_SLOTS:
+ void thumbnailDestroyed(QObject *object);
+ void thumbnailTargetChanged();
private:
+ void insertThumbnail(ThumbnailItem *item);
Toplevel* toplevel;
Scene::Window* sw; // This one is used only during paint pass.
QHash dataMap;
+ QHash > m_thumbnails;
};
class EffectWindowGroupImpl
diff --git a/kcmkwin/kwintabbox/CMakeLists.txt b/kcmkwin/kwintabbox/CMakeLists.txt
index 0616945a6a..6de43c9e00 100644
--- a/kcmkwin/kwintabbox/CMakeLists.txt
+++ b/kcmkwin/kwintabbox/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories( ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox )
set(kcm_kwintabbox_PART_SRCS
main.cpp
layoutconfig.cpp
+ thumbnailitem.cpp
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/clientitemdelegate.cpp
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/clientmodel.cpp
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/declarative.cpp
@@ -27,3 +28,4 @@ install(TARGETS kcm_kwintabbox DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES kwintabbox.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install( FILES qml/main.qml DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox)
+install( FILES thumbnails/konqueror.png thumbnails/kmail.png thumbnails/systemsettings.png thumbnails/dolphin.png DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox)
diff --git a/kcmkwin/kwintabbox/layoutconfig.cpp b/kcmkwin/kwintabbox/layoutconfig.cpp
index 6fb0b47134..84b7d30845 100644
--- a/kcmkwin/kwintabbox/layoutconfig.cpp
+++ b/kcmkwin/kwintabbox/layoutconfig.cpp
@@ -19,6 +19,7 @@ along with this program. If not, see .
*********************************************************************/
// own
#include "layoutconfig.h"
+#include "thumbnailitem.h"
#include
#include
#include
@@ -60,6 +61,7 @@ LayoutConfig::LayoutConfig(QWidget* parent)
kdeclarative.setDeclarativeEngine(engine());
kdeclarative.initialize();
kdeclarative.setupBindings();
+ qmlRegisterType("org.kde.kwin", 0, 1, "ThumbnailItem");
rootContext()->setContextProperty("clientModel", model);
rootContext()->setContextProperty("layoutModel", m_layoutsModels);
setSource(KStandardDirs::locate("data", "kwin/kcm_kwintabbox/main.qml"));
@@ -131,6 +133,7 @@ ExampleClientModel::ExampleClientModel (QObject* parent)
roles[Qt::UserRole] = "caption";
roles[Qt::UserRole+1] = "minimized";
roles[Qt::UserRole+2] = "desktopName";
+ roles[Qt::UserRole+4] = "windowId";
setRoleNames(roles);
init();
}
@@ -167,6 +170,18 @@ QVariant ExampleClientModel::data(const QModelIndex &index, int role) const
return i18nc("An example Desktop Name", "Desktop 1");
case Qt::UserRole+3:
return KDesktopFile(m_nameList.at(index.row())).readIcon();
+ case Qt::UserRole+4:
+ const QString desktopFile = KDesktopFile(m_nameList.at(index.row())).fileName().split('/').last();
+ if (desktopFile == "konqbrowser.desktop") {
+ return ThumbnailItem::Konqueror;
+ } else if (desktopFile == "KMail2.desktop") {
+ return ThumbnailItem::KMail;
+ } else if (desktopFile == "systemsettings.desktop") {
+ return ThumbnailItem::Systemsettings;
+ } else if (desktopFile == "dolphin.desktop") {
+ return ThumbnailItem::Dolphin;
+ }
+ return 0;
}
return QVariant();
}
@@ -194,8 +209,9 @@ LayoutModel::~LayoutModel()
void LayoutModel::init()
{
QStringList layouts;
- layouts << "informative" << "compact" << "text" << "big_icons" << "small_icons";
+ layouts << "thumbnails" << "informative" << "compact" << "text" << "big_icons" << "small_icons";
QStringList descriptions;
+ descriptions << i18nc("Name for a window switcher layout showing live window thumbnails", "Thumbnails");
descriptions << i18nc("Name for a window switcher layout showing icon, name and desktop", "Informative");
descriptions << i18nc("Name for a window switcher layout showing only icon and name", "Compact");
descriptions << i18nc("Name for a window switcher layout showing only the name", "Text");
diff --git a/kcmkwin/kwintabbox/thumbnailitem.cpp b/kcmkwin/kwintabbox/thumbnailitem.cpp
new file mode 100644
index 0000000000..d65c30ca4e
--- /dev/null
+++ b/kcmkwin/kwintabbox/thumbnailitem.cpp
@@ -0,0 +1,89 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#include "thumbnailitem.h"
+// Qt
+#include
+#include
+#include
+// KDE
+#include
+#include
+
+namespace KWin
+{
+ThumbnailItem::ThumbnailItem(QDeclarativeItem* parent)
+ : QDeclarativeItem(parent)
+ , m_wId(0)
+ , m_image()
+{
+ setFlags(flags() & ~QGraphicsItem::ItemHasNoContents);
+}
+
+ThumbnailItem::~ThumbnailItem()
+{
+}
+
+void ThumbnailItem::setWId(qulonglong wId)
+{
+ m_wId = wId;
+ emit wIdChanged(wId);
+ findImage();
+}
+
+void ThumbnailItem::findImage()
+{
+ QString imagePath;
+ switch (m_wId) {
+ case Konqueror:
+ imagePath = KStandardDirs::locate("data", "kwin/kcm_kwintabbox/konqueror.png");
+ break;
+ case Systemsettings:
+ imagePath = KStandardDirs::locate("data", "kwin/kcm_kwintabbox/systemsettings.png");
+ break;
+ case KMail:
+ imagePath = KStandardDirs::locate("data", "kwin/kcm_kwintabbox/kmail.png");
+ break;
+ case Dolphin:
+ imagePath = KStandardDirs::locate("data", "kwin/kcm_kwintabbox/dolphin.png");
+ break;
+ default:
+ // ignore
+ break;
+ }
+ if (imagePath.isNull()) {
+ m_image = QImage();
+ } else {
+ m_image = QImage(imagePath);
+ }
+}
+
+void ThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (m_image.isNull()) {
+ // no image: default behavior
+ QDeclarativeItem::paint(painter, option, widget);
+ }
+ QSizeF difference(boundingRect().width() - m_image.width(), boundingRect().height() - m_image.height());
+ const QRectF drawRect(boundingRect().x() + difference.width()/2.0, boundingRect().y(), m_image.width(), m_image.height());
+ painter->drawImage(drawRect, m_image);
+}
+
+} // namespace KWin
diff --git a/kcmkwin/kwintabbox/thumbnailitem.h b/kcmkwin/kwintabbox/thumbnailitem.h
new file mode 100644
index 0000000000..04977d6d6f
--- /dev/null
+++ b/kcmkwin/kwintabbox/thumbnailitem.h
@@ -0,0 +1,59 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#ifndef KWIN_THUMBNAILITEM_H
+#define KWIN_THUMBNAILITEM_H
+
+#include
+
+namespace KWin
+{
+
+class ThumbnailItem : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
+public:
+ ThumbnailItem(QDeclarativeItem *parent = 0);
+ virtual ~ThumbnailItem();
+
+ qulonglong wId() const {
+ return m_wId;
+ }
+ void setWId(qulonglong wId);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ enum Thumbnail {
+ Konqueror = 1,
+ KMail,
+ Systemsettings,
+ Dolphin
+ };
+Q_SIGNALS:
+ void wIdChanged(qulonglong wid);
+private:
+ void findImage();
+ qulonglong m_wId;
+ QImage m_image;
+};
+
+} // KWin
+
+#endif // KWIN_THUMBNAILITEM_H
diff --git a/kcmkwin/kwintabbox/thumbnails/dolphin.png b/kcmkwin/kwintabbox/thumbnails/dolphin.png
new file mode 100644
index 0000000000..23b56a9359
Binary files /dev/null and b/kcmkwin/kwintabbox/thumbnails/dolphin.png differ
diff --git a/kcmkwin/kwintabbox/thumbnails/kmail.png b/kcmkwin/kwintabbox/thumbnails/kmail.png
new file mode 100644
index 0000000000..0d7f755b0d
Binary files /dev/null and b/kcmkwin/kwintabbox/thumbnails/kmail.png differ
diff --git a/kcmkwin/kwintabbox/thumbnails/konqueror.png b/kcmkwin/kwintabbox/thumbnails/konqueror.png
new file mode 100644
index 0000000000..bb8c927774
Binary files /dev/null and b/kcmkwin/kwintabbox/thumbnails/konqueror.png differ
diff --git a/kcmkwin/kwintabbox/thumbnails/systemsettings.png b/kcmkwin/kwintabbox/thumbnails/systemsettings.png
new file mode 100644
index 0000000000..2018e1490a
Binary files /dev/null and b/kcmkwin/kwintabbox/thumbnails/systemsettings.png differ
diff --git a/scene.cpp b/scene.cpp
index 413e46fb8a..81ca9378a8 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -81,6 +81,7 @@ along with this program. If not, see .
#include "shadow.h"
#include
+#include "thumbnailitem.h"
namespace KWin
{
@@ -388,6 +389,44 @@ void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quad
WindowPaintData data(w->window()->effectWindow());
data.quads = quads;
effects->paintWindow(effectWindow(w), mask, region, data);
+ // paint thumbnails on top of window
+ EffectWindowImpl *wImpl = static_cast(effectWindow(w));
+ for (QHash >::const_iterator it = wImpl->thumbnails().constBegin();
+ it != wImpl->thumbnails().constEnd();
+ ++it) {
+ if (it.value().isNull()) {
+ continue;
+ }
+ ThumbnailItem *item = it.key();
+ if (!item->isVisible()) {
+ continue;
+ }
+ EffectWindowImpl *thumb = it.value().data();
+ WindowPaintData thumbData(thumb);
+ thumbData.opacity = data.opacity;
+
+ QSizeF size = QSizeF(thumb->size());
+ size.scale(QSizeF(item->sceneBoundingRect().width(), item->sceneBoundingRect().height()), Qt::KeepAspectRatio);
+ thumbData.xScale = size.width() / static_cast(thumb->width());
+ thumbData.yScale = size.height() / static_cast(thumb->height());
+ const int x = item->scenePos().x() + w->x() + (item->width() - size.width()) / 2;
+ const int y = item->scenePos().y() + w->y() + (item->height() - size.height()) / 2;
+ thumbData.xTranslate = x - thumb->x();
+ thumbData.yTranslate = y - thumb->y();
+ int thumbMask = PAINT_WINDOW_TRANSFORMED | PAINT_WINDOW_LANCZOS;
+ if (thumbData.opacity == 1.0) {
+ thumbMask |= PAINT_WINDOW_OPAQUE;
+ } else {
+ thumbMask |= PAINT_WINDOW_TRANSLUCENT;
+ }
+ if (x < wImpl->x() || x + size.width() > wImpl->x() + wImpl->width() ||
+ y < wImpl->y() || y + size.height() > wImpl->y() + wImpl->height()) {
+ // don't render windows outside the containing window.
+ // TODO: improve by spliting out the window quads which do not fit
+ continue;
+ }
+ effects->drawWindow(thumb, thumbMask, QRegion(x, y, size.width(), size.height()), thumbData);
+ }
}
// the function that'll be eventually called by paintWindow() above
diff --git a/tabbox/clientmodel.cpp b/tabbox/clientmodel.cpp
index d7f10541d2..eea8c91726 100644
--- a/tabbox/clientmodel.cpp
+++ b/tabbox/clientmodel.cpp
@@ -42,6 +42,7 @@ ClientModel::ClientModel(QObject* parent)
roles[CaptionRole] = "caption";
roles[DesktopNameRole] = "desktopName";
roles[MinimizedRole] = "minimized";
+ roles[WIdRole] = "windowId";
setRoleNames(roles);
}
diff --git a/tabbox/declarative.cpp b/tabbox/declarative.cpp
index 4d92127ac9..08b41e0b7c 100644
--- a/tabbox/declarative.cpp
+++ b/tabbox/declarative.cpp
@@ -37,6 +37,8 @@ along with this program. If not, see .
#include
#include
#include
+// KWin
+#include "thumbnailitem.h"
namespace KWin
{
@@ -103,6 +105,8 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
kdeclarative.setDeclarativeEngine(engine());
kdeclarative.initialize();
kdeclarative.setupBindings();
+ qmlRegisterType("org.kde.kwin", 0, 1, "ThumbnailItem");
+ rootContext()->setContextProperty("viewId", static_cast(winId()));
rootContext()->setContextProperty("clientModel", model);
setSource(QUrl(KStandardDirs::locate("data", "kwin/tabbox/tabbox.qml")));
diff --git a/tabbox/qml/thumbnails.qml b/tabbox/qml/thumbnails.qml
new file mode 100644
index 0000000000..71f16f472f
--- /dev/null
+++ b/tabbox/qml/thumbnails.qml
@@ -0,0 +1,167 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+import QtQuick 1.0
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.qtextracomponents 0.1
+import org.kde.kwin 0.1 as KWin
+
+Item {
+ id: thumbnailTabBox
+ property int screenWidth : 1
+ property int screenHeight : 1
+ property real screenFactor: screenWidth/screenHeight
+ property int imagePathPrefix: (new Date()).getTime()
+ property int optimalWidth: (thumbnailListView.thumbnailWidth + hoverItem.margins.left + hoverItem.margins.right) * thumbnailListView.count + background.margins.left + background.margins.bottom
+ property int optimalHeight: thumbnailListView.thumbnailWidth*(1.0/screenFactor) + hoverItem.margins.top + hoverItem.margins.bottom + background.margins.top + background.margins.bottom + 40
+ property bool canStretchX: false
+ property bool canStretchY: false
+ width: Math.min(Math.max(screenWidth * 0.3, optimalWidth), screenWidth * 0.9)
+ height: Math.min(Math.max(screenHeight * 0.15, optimalHeight), screenHeight * 0.7)
+ clip: true
+
+
+ function setModel(model) {
+ thumbnailListView.model = model;
+ thumbnailListView.imageId++;
+ }
+
+ function modelChanged() {
+ thumbnailListView.imageId++;
+ }
+
+ PlasmaCore.FrameSvgItem {
+ id: background
+ anchors.fill: parent
+ imagePath: "dialogs/background"
+ }
+ // just to get the margin sizes
+ PlasmaCore.FrameSvgItem {
+ id: hoverItem
+ imagePath: "widgets/viewitem"
+ prefix: "hover"
+ visible: false
+ }
+
+ PlasmaCore.Theme {
+ id: theme
+ }
+
+ ListView {
+ /**
+ * Called from C++ to get the index at a mouse pos.
+ **/
+ function indexAtMousePos(pos) {
+ return thumbnailListView.indexAt(pos.x, pos.y);
+ }
+ signal currentIndexChanged(int index)
+ id: thumbnailListView
+ objectName: "listView"
+ orientation: ListView.Horizontal
+ // used for image provider URL to trick Qt into reloading icons when the model changes
+ property int imageId: 0
+ property int thumbnailWidth: 300
+ height: thumbnailWidth * (1.0/screenFactor) + hoverItem.margins.bottom + hoverItem.margins.top
+ spacing: 5
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ topMargin: background.margins.top
+ leftMargin: background.margins.left
+ rightMargin: background.margins.right
+ bottomMargin: background.margins.bottom
+ }
+ clip: true
+ delegate: Item {
+ property alias data: thumbnailItem.data
+ id: delegateItem
+ width: thumbnailListView.thumbnailWidth
+ height: thumbnailListView.thumbnailWidth*(1.0/screenFactor)
+ KWin.ThumbnailItem {
+ property variant data: model
+ id: thumbnailItem
+ wId: windowId
+ anchors {
+ fill: parent
+ leftMargin: hoverItem.margins.left
+ rightMargin: hoverItem.margins.right
+ topMargin: hoverItem.margins.top
+ bottomMargin: hoverItem.margins.bottom
+ }
+ }
+ }
+ highlight: PlasmaCore.FrameSvgItem {
+ id: highlightItem
+ imagePath: "widgets/viewitem"
+ prefix: "hover"
+ width: thumbnailListView.thumbnailWidth
+ height: thumbnailListView.thumbnailWidth*(1.0/screenFactor)
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ thumbnailListView.currentIndex = thumbnailListView.indexAt(mouse.x, mouse.y);
+ thumbnailListView.currentIndexChanged(thumbnailListView.currentIndex);
+ }
+ }
+ }
+ Item {
+ height: 40
+ anchors {
+ top: thumbnailListView.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ topMargin: hoverItem.margins.bottom
+ leftMargin: background.margins.left
+ rightMargin: background.margins.right
+ bottomMargin: background.margins.bottom
+ }
+ Image {
+ id: iconItem
+ source: "image://client/" + thumbnailListView.currentIndex + "/" + thumbnailTabBox.imagePathPrefix + "-" + thumbnailListView.imageId
+ width: 32
+ height: 32
+ sourceSize {
+ width: 32
+ height: 32
+ }
+ anchors {
+ verticalCenter: parent.verticalCenter
+ right: textItem.left
+ rightMargin: 4
+ }
+ }
+ Text {
+ id: textItem
+ text: thumbnailListView.currentItem ? thumbnailListView.currentItem.data.caption : ""
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: theme.textColor
+ font {
+ bold: true
+ }
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+}
diff --git a/thumbnailitem.cpp b/thumbnailitem.cpp
new file mode 100644
index 0000000000..8c209833f0
--- /dev/null
+++ b/thumbnailitem.cpp
@@ -0,0 +1,113 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#include "thumbnailitem.h"
+// KWin
+#include "client.h"
+#include "effects.h"
+#include "workspace.h"
+// Qt
+#include
+#include
+#include
+// KDE
+#include
+
+namespace KWin
+{
+ThumbnailItem::ThumbnailItem(QDeclarativeItem* parent)
+ : QDeclarativeItem(parent)
+ , m_wId(0)
+ , m_parent(QWeakPointer())
+{
+ setFlags(flags() & ~QGraphicsItem::ItemHasNoContents);
+ if (effects) {
+ connect(effects, SIGNAL(windowAdded(EffectWindow*)), SLOT(effectWindowAdded()));
+ }
+ QTimer::singleShot(0, this, SLOT(init()));
+}
+
+ThumbnailItem::~ThumbnailItem()
+{
+}
+
+void ThumbnailItem::init()
+{
+ findParentEffectWindow();
+ if (!m_parent.isNull()) {
+ m_parent.data()->registerThumbnail(this);
+ }
+}
+
+void ThumbnailItem::findParentEffectWindow()
+{
+ if (effects) {
+ QDeclarativeContext *ctx = QDeclarativeEngine::contextForObject(this);
+ if (!ctx) {
+ kDebug(1212) << "No Context";
+ return;
+ }
+ const QVariant variant = ctx->engine()->rootContext()->contextProperty("viewId");
+ if (!variant.isValid()) {
+ kDebug(1212) << "Required context property 'viewId' not found";
+ return;
+ }
+ if (EffectWindowImpl *w = static_cast(effects->findWindow(variant.value()))) {
+ m_parent = QWeakPointer(w);
+ }
+ }
+}
+
+void ThumbnailItem::setWId(qulonglong wId)
+{
+ m_wId = wId;
+ emit wIdChanged(wId);
+}
+
+void ThumbnailItem::effectWindowAdded()
+{
+ // the window might be added before the EffectWindow is created
+ // by using this slot we can register the thumbnail when it is finally created
+ if (m_parent.isNull()) {
+ findParentEffectWindow();
+ if (!m_parent.isNull()) {
+ m_parent.data()->registerThumbnail(this);
+ }
+ }
+}
+
+void ThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (effects) {
+ QDeclarativeItem::paint(painter, option, widget);
+ return;
+ }
+ Client *client = Workspace::self()->findClient(WindowMatchPredicate(m_wId));
+ if (!client) {
+ QDeclarativeItem::paint(painter, option, widget);
+ return;
+ }
+ QPixmap pixmap = client->icon(boundingRect().size().toSize());
+ const QSize size(boundingRect().size().toSize() - pixmap.size());
+ painter->drawPixmap(boundingRect().adjusted(size.width()/2.0, size.height()/2.0, -size.width()/2.0, -size.height()/2.0).toRect(),
+ pixmap);
+}
+
+} // namespace KWin
diff --git a/thumbnailitem.h b/thumbnailitem.h
new file mode 100644
index 0000000000..2ff354672f
--- /dev/null
+++ b/thumbnailitem.h
@@ -0,0 +1,59 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Martin Gräßlin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#ifndef KWIN_THUMBNAILITEM_H
+#define KWIN_THUMBNAILITEM_H
+
+#include
+#include
+
+namespace KWin
+{
+
+class EffectWindow;
+class EffectWindowImpl;
+
+class ThumbnailItem : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
+public:
+ ThumbnailItem(QDeclarativeItem *parent = 0);
+ virtual ~ThumbnailItem();
+
+ qulonglong wId() const {
+ return m_wId;
+ }
+ void setWId(qulonglong wId);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+Q_SIGNALS:
+ void wIdChanged(qulonglong wid);
+private Q_SLOTS:
+ void init();
+ void effectWindowAdded();
+private:
+ void findParentEffectWindow();
+ qulonglong m_wId;
+ QWeakPointer m_parent;
+};
+
+} // KWin
+
+#endif // KWIN_THUMBNAILITEM_H