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