File plasma-libs.diff of Package kdebase4-workspace

Patch-rediff: rediff-plasma.sh

--- plasma/servicetypes/plasma-dataengine.desktop	
+++ plasma/servicetypes/plasma-dataengine.desktop	
@@ -36,7 +36,7 @@
 Comment[ml]=പ്ലാസ്മാ ഡേറ്റാ എഞ്ചിന്‍
 Comment[mr]=प्लाज्मा माहिती इंजिन
 Comment[nb]=Plasma datamotor
-Comment[nds]=Plasma-Hanteerkarn
+Comment[nds]=Plasma-Datenkarn
 Comment[ne]=प्लाज्मा डेटा इन्जिन
 Comment[nl]=Plasma-gegevensengine
 Comment[nn]=Plasma-datamotor
@@ -48,8 +48,8 @@
 Comment[ru]=Движок данных Plasma
 Comment[se]=Plasma-dáhtámohtor
 Comment[sl]=Podatkovni pogon za Plasmo
-Comment[sr]=Плазмин мотор
-Comment[sr@latin]=Plasmin motor
+Comment[sr]=Плазма датомотор
+Comment[sr@latin]=Plasma datomotor
 Comment[sv]=Plasma datagränssnitt
 Comment[th]=กลไกข้อมูลของพลาสมา
 Comment[tr]=Plasma Veri Motoru
--- plasma/servicetypes/plasma-wallpaper.desktop	
+++ plasma/servicetypes/plasma-wallpaper.desktop	
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=Plasma/Wallpaper
+
+Comment=Plasma wallpaper
+
+[PropertyDef::X-Plasma-FormFactors]
+Type=QStringList
+
--- plasma/servicetypes/plasma-runner.desktop	
+++ plasma/servicetypes/plasma-runner.desktop	
@@ -45,7 +45,7 @@
 Comment[pa]=ਕੇ-ਰਨਰ ਪਲੱਗਇਨ
 Comment[pl]=Wtyczki KRunnera
 Comment[pt]='Plugin' do KRunner
-Comment[pt_BR]=Plugin do KRunner
+Comment[pt_BR]=Plug-in do KRunner
 Comment[ro]=Modlú KRunner
 Comment[ru]=Модуль KRunner
 Comment[se]=KRunner-lassemodula
--- plasma/servicetypes/plasma-animator.desktop	
+++ plasma/servicetypes/plasma-animator.desktop	
@@ -47,8 +47,8 @@
 Comment[ru]=Движок анимации Plasma
 Comment[se]=Plasma-animerenmohtor
 Comment[sl]=Animacijski pogon za Plasmo
-Comment[sr]=Плазмин мотор за анимације
-Comment[sr@latin]=Plasmin motor za animacije
+Comment[sr]=Плазма мотор анимација
+Comment[sr@latin]=Plasma motor animacija
 Comment[sv]=Animeringsgränssnitt i Plasma
 Comment[th]=กลไกการแสดงการเคลื่อนไหลของพลาสมา
 Comment[tr]=Plasma Canlandırma Motoru
--- plasma/applet_p.h	
+++ plasma/applet_p.h	
@@ -30,6 +30,7 @@
 class PanelSvg;
 class AppletScript;
 class ShadowItem;
+class Wallpaper;
 
 class AppletOverlayWidget : public QGraphicsWidget
 {
@@ -63,6 +64,7 @@
     void resetConfigurationObject();
     void appletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim);
     void selectItemToDestroy();
+    void updateRect(const QRectF& rect);
     void setFocus();
     void cleanUpAndDelete();
 
--- plasma/corona.cpp	
+++ plasma/corona.cpp	
@@ -119,7 +119,9 @@
 
         if (pluginName.isEmpty()) {
             // default to the desktop containment
-            pluginName = "desktop";
+            KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc");
+            KConfigGroup group = KConfigGroup(defaultconfig, "Defaults");
+            pluginName = group.readEntry("containment", "desktop");
         }
 
         if (pluginName != "null") {
@@ -134,6 +136,10 @@
             delete applet;
             containment = new Containment(0, 0, id);
 
+            if (pluginName == "null") {
+                containment->setDrawWallpaper(false);
+            }
+
             // we want to provide something and don't care about the failure to launch
             containment->setFailedToLaunch(false);
             containment->setFormFactor(Plasma::Planar);
@@ -314,6 +320,11 @@
     return 0;
 }
 
+bool Corona::loadDefaultApplets(Plasma::Containment*, bool)
+{
+    return true;
+}
+
 QList<Containment*> Corona::containments() const
 {
     return d->containments;
--- plasma/plasma.h	
+++ plasma/plasma.h	
@@ -25,6 +25,8 @@
 
 #include <plasma/plasma_export.h>
 
+class QGraphicsView;
+
 /**
  * Namespace for everything in libplasma
  */
@@ -193,6 +195,22 @@
  **/
 PLASMA_EXPORT Direction locationToDirection(Location location);
 
+/**
+ * Reccomended position for a popup window like a menu or a tooltip
+ * given its size
+ * @param s size of the popup
+ * @returns reccomended position
+ */
+PLASMA_EXPORT QPoint popupPosition(const QGraphicsItem *item, const QSize &s);
+
+/**
+ * Returns the most appropriate QGraphicsView for the item.
+ *
+ * @arg item the QGraphicsItem to locate a view for
+ * @return pointer to a view, or 0 if none was found
+ */
+PLASMA_EXPORT QGraphicsView *viewFor(const QGraphicsItem *item);
+
 } // Plasma namespace
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::Constraints)
--- plasma/includes/ToolTipManager	
+++ plasma/includes/ToolTipManager	
@@ -0,0 +1 @@
+#include "../../plasma/tooltipmanager.h"
--- plasma/includes/Wallpaper	
+++ plasma/includes/Wallpaper	
@@ -0,0 +1 @@
+#include "../../plasma/wallpaper.h"
--- plasma/includes/ScrollBar	
+++ plasma/includes/ScrollBar	
@@ -0,0 +1 @@
+#include "../../plasma/widgets/scrollbar.h"
--- plasma/tooltipmanager.cpp	
+++ plasma/tooltipmanager.cpp	
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ * Copyright 2008 by Aaron Seigo <aseigo@kde.org>
+ * Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#include "tooltipmanager.h"
+
+//Qt
+#include <QLabel>
+#include <QTimer>
+#include <QGridLayout>
+#include <QGraphicsView>
+#include <QDesktopWidget>
+
+//KDE
+#include <KWindowSystem>
+
+//X11
+#ifdef Q_WS_X11
+#include <QtGui/QX11Info>
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#endif
+
+
+//Plasma
+#include <applet.h>
+#include <containment.h>
+#include <panelsvg.h>
+#include <theme.h>
+#include <view.h>
+#include <private/tooltip_p.h>
+
+namespace Plasma
+{
+
+class ToolTipManagerPrivate
+{
+public :
+    ToolTipManagerPrivate()
+        : currentWidget(0),
+          showTimer(0),
+          hideTimer(0),
+          isShown(false),
+          delayedHide(false)
+    {
+
+    }
+    ~ToolTipManagerPrivate()
+    {
+
+    }
+
+    void showToolTip();
+    void resetShownState();
+
+    /**
+      * called when the theme of plasma has change
+      */
+    void themeUpdated();
+    /**
+      * called when a widget inside the tooltip manager is deleted
+      */
+    void onWidgetDestroyed(QObject * object);
+
+
+    QGraphicsWidget *currentWidget;
+    QTimer *showTimer;
+    QTimer *hideTimer;
+    QHash<QGraphicsWidget *, ToolTip *> tooltips;
+    bool isShown : 1;
+    bool delayedHide : 1;
+};
+
+//TOOLTIP IMPLEMENTATION
+class ToolTipManagerSingleton
+{
+    public:
+    ToolTipManagerSingleton()
+    {
+    }
+    ToolTipManager self;
+};
+K_GLOBAL_STATIC( ToolTipManagerSingleton, privateInstance )
+
+ToolTipManager *ToolTipManager::self()
+{
+    return &privateInstance->self;
+}
+
+ToolTipManager::ToolTipContent::ToolTipContent()
+    : windowToPreview(0)
+{
+}
+
+bool ToolTipManager::ToolTipContent::isEmpty() const
+{
+    return mainText.isEmpty() && subText.isEmpty() && image.isNull() && windowToPreview == 0;
+}
+
+ToolTipManager::ToolTipManager(QObject* parent)
+  : QObject(parent),
+    d(new ToolTipManagerPrivate)
+{
+    connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeUpdated()));
+    d->themeUpdated();
+
+    d->showTimer = new QTimer(this);
+    d->showTimer->setSingleShot(true);
+    d->hideTimer = new QTimer(this);
+    d->hideTimer->setSingleShot(true);
+
+    connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
+    connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
+}
+
+ToolTipManager::~ToolTipManager()
+{
+    delete d;
+}
+
+void ToolTipManager::showToolTip(QGraphicsWidget *widget)
+{
+    if (!d->tooltips.contains(widget)) {
+        return;
+    }
+
+    if (d->currentWidget) {
+        hideToolTip(d->currentWidget);
+    }
+
+    d->hideTimer->stop();
+    d->delayedHide = false;
+    d->showTimer->stop();
+    d->currentWidget = widget;
+
+    if (d->isShown) {
+        // small delay to prevent unnecessary showing when the mouse is moving quickly across items
+        // which can be too much for less powerful CPUs to keep up with
+        d->showTimer->start(200);
+    } else {
+        d->showTimer->start(500);
+    }
+}
+
+bool ToolTipManager::isWidgetToolTipDisplayed(QGraphicsWidget *widget)
+{
+    ToolTip *tooltip = d->tooltips.value(widget);
+    if (tooltip) {
+        return tooltip->isVisible();
+    } else {
+        return false;
+    }
+}
+
+void ToolTipManager::delayedHideToolTip()
+{
+    d->showTimer->stop();  // stop the timer to show the tooltip
+    d->delayedHide = true;
+    d->hideTimer->start(250);
+}
+
+void ToolTipManager::hideToolTip(QGraphicsWidget *widget)
+{
+    ToolTip *tooltip = d->tooltips.value(widget);
+    if (tooltip) {
+        d->showTimer->stop();  // stop the timer to show the tooltip
+        d->delayedHide = false;
+        d->currentWidget = 0;
+        tooltip->hide();
+    }
+}
+
+void ToolTipManager::registerWidget(QGraphicsWidget *widget)
+{
+    if (d->tooltips.contains(widget)) {
+        return;
+    }
+
+    //the tooltip is not registered we add it in our map of tooltips
+    d->tooltips.insert(widget, 0);
+    widget->installEventFilter(this);
+    //connect to object destruction
+    connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onWidgetDestroyed(QObject*)));
+}
+
+void ToolTipManager::unregisterWidget(QGraphicsWidget *widget)
+{
+    if (!d->tooltips.contains(widget)) {
+        return;
+    }
+
+    widget->removeEventFilter(this);
+    ToolTip *tooltip = d->tooltips.take(widget);
+    if (tooltip) {
+        tooltip->deleteLater();
+    }
+}
+
+void ToolTipManager::setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data)
+{
+    registerWidget(widget);
+
+    ToolTip *tooltip = d->tooltips.value(widget);
+
+    if (data.isEmpty()) {
+        if (tooltip) {
+            tooltip->deleteLater();
+        }
+        d->tooltips.insert(widget, 0);
+        return;
+    }
+
+    if (!tooltip) {
+        tooltip = new ToolTip(widget);
+        d->tooltips.insert(widget, tooltip);
+    }
+
+    tooltip->setContent(data);
+    tooltip->updateTheme();
+}
+
+void ToolTipManager::clearToolTipContent(QGraphicsWidget *widget)
+{
+    ToolTipContent t;
+    setToolTipContent(widget, t);
+}
+
+bool ToolTipManager::widgetHasToolTip(QGraphicsWidget *widget) const
+{
+    return d->tooltips.contains(widget);
+}
+
+void ToolTipManager::setToolTipActivated(QGraphicsWidget *widget, bool enable)
+{
+    registerWidget(widget);
+
+    ToolTip *tooltip = d->tooltips.value(widget);
+    tooltip->setActivated(enable);
+    if (!enable) {
+        hideToolTip(widget);
+    } else if (d->currentWidget) {
+        showToolTip(widget);
+    }
+}
+
+bool ToolTipManager::isToolTipActivated(QGraphicsWidget *widget)
+{
+    if (!d->tooltips.contains(widget)) {
+        return false;
+    }
+
+    ToolTip *tooltip = d->tooltips.value(widget);
+    return tooltip->isActivated();
+}
+
+void ToolTipManagerPrivate::themeUpdated()
+{
+    QHashIterator<QGraphicsWidget*, ToolTip *> iterator(tooltips);
+    while (iterator.hasNext()) {
+        iterator.next();
+        if (iterator.value()) {
+            iterator.value()->updateTheme();
+        }
+    }
+}
+
+void ToolTipManagerPrivate::onWidgetDestroyed(QObject *object)
+{
+    if (!object) {
+        return;
+    }
+
+    // we do a static_cast here since it really isn't a QGraphicsWidget by this
+    // point anymore since we are in the QObject dtor. we don't actually
+    // try and do anything with it, we just need the value of the pointer
+    // so this unsafe looking code is actually just fine.
+    //
+    // NOTE: DO NOT USE THE w VARIABLE FOR ANYTHING OTHER THAN COMPARING
+    //       THE ADDRESS! ACTUALLY USING THE OBJECT WILL RESULT IN A CRASH!!!
+    QGraphicsWidget *w = static_cast<QGraphicsWidget*>(object);
+
+    if (currentWidget == w) {
+        currentWidget = 0;
+        showTimer->stop();  // stop the timer to show the tooltip
+        delayedHide = false;
+    }
+
+    QMutableHashIterator<QGraphicsWidget*, ToolTip *> iterator(tooltips);
+    while (iterator.hasNext()) {
+        iterator.next();
+        //kDebug() << (int)iterator.key() << (int)w;
+        if (iterator.key() == w) {
+            ToolTip *tooltip = iterator.value();
+            iterator.remove();
+            if (tooltip) {
+                //kDebug() << "deleting the tooltip!";
+                tooltip->hide();
+                tooltip->deleteLater();
+            }
+            return;
+        }
+    }
+}
+
+void ToolTipManagerPrivate::resetShownState()
+{
+    if (currentWidget) {
+        ToolTip * tooltip = tooltips.value(currentWidget);
+        if (tooltip && (!tooltip->isVisible() || delayedHide)) {
+            //One might have moused out and back in again
+            delayedHide = false;
+            isShown = false;
+            tooltip->hide();
+            currentWidget = 0;
+      }
+    }
+}
+
+void ToolTipManagerPrivate::showToolTip()
+{
+    if (!currentWidget) {
+        return;
+    }
+
+    ToolTip *tooltip = tooltips.value(currentWidget);
+    bool justCreated = false;
+
+    if (!tooltip) {
+        // give the object a chance for delayed loading of the tip
+        QMetaObject::invokeMethod(currentWidget, "toolTipAboutToShow");
+        tooltip = tooltips.value(currentWidget);
+        if (tooltip) {
+            justCreated = true;
+        } else {
+            currentWidget = 0;
+            return;
+        }
+    }
+
+    if (tooltip->isActivated()) {
+        tooltip->setVisible(false);
+        //kDebug() << "about to show" << justCreated;
+        tooltip->prepareShowing(!justCreated);
+        tooltip->move(popupPosition(currentWidget, tooltip->size()));
+        isShown = true;  //ToolTip is visible
+        tooltip->setVisible(true);
+    }
+}
+
+bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
+{
+    QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched);
+    if (!widget) {
+        return QObject::eventFilter(watched, event);
+    }
+
+    switch (event->type()) {
+        case QEvent::GraphicsSceneHoverMove:
+            // If the tooltip isn't visible, run through showing the tooltip again
+            // so that it only becomes visible after a stationary hover
+            if (Plasma::ToolTipManager::self()->isWidgetToolTipDisplayed(widget)) {
+                break;
+            }
+
+            // Don't restart the show timer on a mouse move event if there hasn't
+            // been an enter event or the current widget has been cleared by a click
+            // or wheel event.
+            if (!d->currentWidget) {
+                break;
+            }
+
+        case QEvent::GraphicsSceneHoverEnter:
+        {
+            // Check that there is a tooltip to show
+            if (!widgetHasToolTip(widget)) {
+                break;
+            }
+
+            // If the mouse is in the widget's area at the time that it is being
+            // created the widget can receive a hover event before it is fully
+            // initialized, in which case view() will return 0.
+            QGraphicsView *parentView = viewFor(widget);
+            if (parentView) {
+                showToolTip(widget);
+            }
+
+            break;
+        }
+
+        case QEvent::GraphicsSceneHoverLeave:
+            delayedHideToolTip();
+            break;
+
+        case QEvent::GraphicsSceneMousePress:
+        case QEvent::GraphicsSceneWheel:
+            hideToolTip(widget);
+
+        default:
+            break;
+    }
+
+    return QObject::eventFilter(watched,event);
+}
+
+} // Plasma namespace
+
+#include "tooltipmanager.moc"
--- plasma/wallpaper.cpp	
+++ plasma/wallpaper.cpp	
@@ -0,0 +1,227 @@
+/*
+ *   Copyright 2008 by Aaron Seigo <aseigo@kde.org>
+ *   Copyright 2008 by Petri Damsten <damu@iki.fi>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "wallpaper.h"
+
+#include <KServiceTypeTrader>
+#include <KDebug>
+
+#include <version.h>
+
+namespace Plasma
+{
+
+class WallpaperPrivate
+{
+public:
+    WallpaperPrivate(KService::Ptr service, Wallpaper *wallpaper) :
+        q(wallpaper),
+        wallpaperDescription(service)
+    {
+    };
+
+    ~WallpaperPrivate()
+    {
+    };
+
+    Wallpaper *q;
+    KPluginInfo wallpaperDescription;
+    QRectF boundingRect;
+    KServiceAction mode;
+};
+
+Wallpaper::Wallpaper(QObject* parentObject, const QVariantList& args)
+    : d(new WallpaperPrivate(KService::serviceByStorageId(args.count() > 0 ?
+                             args[0].toString() : QString()), this))
+{
+    // now remove first item since those are managed by Wallpaper and subclasses shouldn't
+    // need to worry about them. yes, it violates the constness of this var, but it lets us add
+    // or remove items later while applets can just pretend that their args always start at 0
+    QVariantList &mutableArgs = const_cast<QVariantList&>(args);
+    if (!mutableArgs.isEmpty()) {
+        mutableArgs.removeFirst();
+    }
+    setParent(parentObject);
+}
+
+Wallpaper::~Wallpaper()
+{
+    delete d;
+}
+
+KPluginInfo::List Wallpaper::listWallpaperInfo(const QString &formFactor)
+{
+    QString constraint;
+
+    if (!formFactor.isEmpty()) {
+        constraint.append("[X-Plasma-FormFactors] ~~ '").append(formFactor).append("'");
+    }
+
+    KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint);
+    return KPluginInfo::fromServices(offers);
+}
+
+Wallpaper* Wallpaper::load(const QString& wallpaperName, const QVariantList& args)
+{
+    if (wallpaperName.isEmpty()) {
+        return 0;
+    }
+
+    QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(wallpaperName);
+    KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint);
+
+    if (offers.isEmpty()) {
+        kDebug() << "offers is empty for " << wallpaperName;
+        return 0;
+    }
+
+    KService::Ptr offer = offers.first();
+    KPluginLoader plugin(*offer);
+
+    if (!Plasma::isPluginVersionCompatible(plugin.pluginVersion())) {
+        return 0;
+    }
+
+    QVariantList allArgs;
+    allArgs << offer->storageId() << args;
+    QString error;
+    Wallpaper* wallpaper = offer->createInstance<Plasma::Wallpaper>(0, allArgs, &error);
+
+    if (!wallpaper) {
+        kDebug() << "Couldn't load wallpaper \"" << wallpaperName << "\"! reason given: " << error;
+    }
+    return wallpaper;
+}
+
+Wallpaper* Wallpaper::load(const KPluginInfo& info, const QVariantList& args)
+{
+    if (!info.isValid()) {
+        return 0;
+    }
+    return load(info.pluginName(), args);
+}
+
+QString Wallpaper::name() const
+{
+    if (!d->wallpaperDescription.isValid()) {
+        return i18n("Unknown Wallpaper");
+    }
+
+    return d->wallpaperDescription.name();
+}
+
+QString Wallpaper::icon() const
+{
+    if (!d->wallpaperDescription.isValid()) {
+        return QString();
+    }
+
+    return d->wallpaperDescription.icon();
+}
+
+QString Wallpaper::pluginName() const
+{
+    if (!d->wallpaperDescription.isValid()) {
+        return QString();
+    }
+
+    return d->wallpaperDescription.pluginName();
+}
+
+KServiceAction Wallpaper::renderingMode() const
+{
+    return d->mode;
+}
+
+QList<KServiceAction> Wallpaper::listRenderingModes() const
+{
+    if (!d->wallpaperDescription.isValid()) {
+        return QList<KServiceAction>();
+    }
+
+    return d->wallpaperDescription.service()->actions();
+}
+
+QRectF Wallpaper::boundingRect() const
+{
+    return d->boundingRect;
+}
+
+void Wallpaper::setBoundingRect(const QRectF& boundingRect)
+{
+    d->boundingRect = boundingRect;
+}
+
+void Wallpaper::restore(const KConfigGroup &config, const QString &mode)
+{
+    d->mode = KServiceAction();
+    if (!mode.isEmpty()) {
+        QList<KServiceAction> modes = listRenderingModes();
+
+        foreach (const KServiceAction &action, modes) {
+            if (action.name() == mode) {
+                d->mode = action;
+                break;
+            }
+        }
+    }
+
+    init(config);
+}
+
+void Wallpaper::init(const KConfigGroup &config)
+{
+    Q_UNUSED(config);
+}
+
+void Wallpaper::save(KConfigGroup &config)
+{
+    Q_UNUSED(config);
+}
+
+QWidget *Wallpaper::createConfigurationInterface(QWidget *parent)
+{
+    Q_UNUSED(parent);
+    return 0;
+}
+
+void Wallpaper::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+}
+
+void Wallpaper::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+}
+
+void Wallpaper::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+}
+
+void Wallpaper::wheelEvent(QGraphicsSceneWheelEvent *event)
+{
+    Q_UNUSED(event)
+}
+
+} // Plasma namespace
+
+#include "wallpaper.moc"
--- plasma/applet.h	
+++ plasma/applet.h	
@@ -513,6 +513,11 @@
         void geometryChanged();
 
         /**
+         * Emitted by Applet subclasses when they change a sizeHint and wants to announce the change
+         */
+        void sizeHintChanged(Qt::SizeHint which);
+
+        /**
          * Emitted when an applet has changed values in its configuration
          * and wishes for them to be saved at the next save point. As this implies
          * disk activity, this signal should be used with care.
@@ -750,6 +755,7 @@
         Q_PRIVATE_SLOT(d, void themeChanged())
         Q_PRIVATE_SLOT(d, void appletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim))
         Q_PRIVATE_SLOT(d, void selectItemToDestroy())
+        Q_PRIVATE_SLOT(d, void updateRect(const QRectF& rect))
 
         /**
          * Reimplemented from QGraphicsItem
--- plasma/plasma.cpp	
+++ plasma/plasma.cpp	
@@ -17,8 +17,15 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-#include <plasma.h>
+#include <plasma/plasma.h>
 
+#include <QDesktopWidget>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+
+#include <plasma/containment.h>
+#include <plasma/view.h>
+
 namespace Plasma
 {
 
@@ -62,4 +69,78 @@
     return Down;
 }
 
+QPoint popupPosition(const QGraphicsItem * item, const QSize &s)
+{
+    QGraphicsView *v = viewFor(item);
+
+    if (!v) {
+        return QPoint(0,0);
+    }
+
+    QPoint pos = v->mapFromScene(item->scenePos());
+    pos = v->mapToGlobal(pos);
+    //kDebug() << "==> position is" << item->scenePos() << v->mapFromScene(item->scenePos()) << pos;
+    Plasma::View *pv = dynamic_cast<Plasma::View *>(v);
+
+    Plasma::Location loc = Floating;
+    if (pv) {
+        loc = pv->containment()->location();
+    }
+
+    switch (loc) {
+    case BottomEdge:
+        pos = QPoint(pos.x(), pos.y() - s.height());
+        break;
+    case TopEdge:
+        pos = QPoint(pos.x(), pos.y() + (int)item->boundingRect().size().height());
+        break;
+    case LeftEdge:
+        pos = QPoint(pos.x() + (int)item->boundingRect().size().width(), pos.y());
+        break;
+    case RightEdge:
+        pos = QPoint(pos.x() - s.width(), pos.y());
+        break;
+    default:
+        if (pos.y() - s.height() > 0) {
+             pos = QPoint(pos.x(), pos.y() - s.height());
+        } else {
+             pos = QPoint(pos.x(), pos.y() + (int)item->boundingRect().size().height());
+        }
+    }
+
+    //are we out of screen?
+    QRect screenRect = QApplication::desktop()->screenGeometry(pv ? pv->containment()->screen() : -1);
+    //kDebug() << "==> rect for" << (pv ? pv->containment()->screen() : -1) << "is" << screenRect;
+
+    if (pos.rx() + s.width() > screenRect.right()) {
+        pos.rx() -= ((pos.rx() + s.width()) - screenRect.right());
+    }
+
+    if (pos.ry() + s.height() > screenRect.bottom()) {
+        pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom());
+    }
+
+    pos.rx() = qMax(0, pos.rx());
+    return pos;
+}
+
+QGraphicsView* viewFor(const QGraphicsItem * item)
+{
+    if (!item->scene()) {
+        return 0;
+    }
+
+    QGraphicsView *found = 0;
+    foreach (QGraphicsView *view, item->scene()->views()) {
+        if (view->sceneRect().intersects(item->sceneBoundingRect()) ||
+            view->sceneRect().contains(item->scenePos())) {
+            if (!found || view->isActiveWindow()) {
+                found = view;
+            }
+        }
+    }
+
+    return found;
+}
+
 } // Plasma namespace
--- plasma/panelsvg.h	
+++ plasma/panelsvg.h	
@@ -119,6 +119,11 @@
         void getMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const;
 
         /**
+         * @return the rectangle of the center element, taking the margins into account.
+         */
+        QRectF contentsRect() const;
+
+        /**
          * Sets the prefix (@see setElementPrefix) to 'north', 'south', 'west' and 'east'
          * when the location is TopEdge, BottomEdge, LeftEdge and RightEdge,
          * respectively. Clears the prefix in other cases.
@@ -195,6 +200,11 @@
          */
         Q_INVOKABLE void paintPanel(QPainter* painter, const QRectF& rect, const QPointF& pos = QPointF(0, 0));
 
+        /**
+         * a convenience method...
+         */
+        Q_INVOKABLE void paintPanel(QPainter* painter, const QPointF& pos = QPointF(0, 0));
+
     private:
         PanelSvgPrivate * const d;
 
--- plasma/widgets/scrollbar.cpp	
+++ plasma/widgets/scrollbar.cpp	
@@ -0,0 +1,104 @@
+/*
+ *   Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
+ *   Copyright © 2008 Marco Martin <notmart@gmail.com> 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "scrollbar.h"
+
+// #include <plasma/style.h>
+
+namespace Plasma
+{
+
+ScrollBar::ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent)
+   : QGraphicsProxyWidget(parent)
+{
+   QScrollBar *scrollbar = new QScrollBar(orientation);
+   scrollbar->setAttribute(Qt::WA_NoSystemBackground);
+   setWidget(scrollbar);
+/*   Plasma::Style *style = new Plasma::Style();
+   scrollbar->setStyle(style); */
+}
+
+ScrollBar::~ScrollBar()
+{
+}
+
+void ScrollBar::setRange(int min, int max)
+{
+   static_cast<QScrollBar*>(widget())->setRange(min, max);
+}
+
+void ScrollBar::setSingleStep(int val)
+{
+   static_cast<QScrollBar*>(widget())->setSingleStep(val);
+}
+
+int ScrollBar::singleStep()
+{
+   return static_cast<QScrollBar*>(widget())->singleStep();
+}
+
+void ScrollBar::setPageStep(int val)
+{
+   static_cast<QScrollBar*>(widget())->setPageStep(val);
+}
+
+int ScrollBar::pageStep()
+{
+   return static_cast<QScrollBar*>(widget())->pageStep();
+}
+
+void ScrollBar::setValue(int val)
+{ 
+   static_cast<QScrollBar*>(widget())->setValue(val);
+}
+
+int ScrollBar::value() const
+{ 
+   return static_cast<QScrollBar*>(widget())->value();
+}
+
+int ScrollBar::minimum() const
+{ 
+   return static_cast<QScrollBar*>(widget())->minimum();
+}
+
+int ScrollBar::maximum() const
+{ 
+   return static_cast<QScrollBar*>(widget())->maximum();
+}
+
+void ScrollBar::setStyleSheet(const QString &stylesheet)
+{
+   widget()->setStyleSheet(stylesheet); 
+}
+
+QString ScrollBar::styleSheet()
+{
+   return widget()->styleSheet();
+}    
+    
+QScrollBar *ScrollBar::nativeWidget() const
+{   
+   return static_cast<QScrollBar*>(widget());
+}
+
+}
+
+#include <scrollbar.moc>
--- plasma/widgets/scrollbar.h	
+++ plasma/widgets/scrollbar.h	
@@ -0,0 +1,124 @@
+/*
+ *   Copyright © 2008 Fredrik Höglund <fredrik@kde.org>
+ *   Copyright © 2008 Marco Martin <notmart@gmail.com> 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef PLASMA_SCROLLBAR_H
+#define PLASMA_SCROLLBAR_H
+
+#include <QtGui/QScrollBar>
+#include <QtGui/QGraphicsProxyWidget>
+
+#include <plasma/plasma_export.h>
+
+namespace Plasma
+{
+
+/**
+ * @class ScrollBar plasma/widgets/scrollbar.h <Plasma/Widgets/ScrollBar>
+ *
+ * @short Provides a plasma-themed QScrollBar.
+ */
+class PLASMA_EXPORT ScrollBar : public QGraphicsProxyWidget
+{
+    Q_OBJECT
+
+    Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+    Q_PROPERTY(int pageStep READ pageStep WRITE setPageStep)
+    Q_PROPERTY(int value READ value WRITE setValue)
+    Q_PROPERTY(int minimum READ minimum)
+    Q_PROPERTY(int maximum READ maximum)
+    Q_PROPERTY(QString stylesheet READ styleSheet WRITE setStyleSheet)
+    Q_PROPERTY(QScrollBar* nativeWidget READ nativeWidget)
+
+public:
+    explicit ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent);
+    ~ScrollBar();
+
+    /**
+     * Sets the scrollbar minimum and maximum values
+     * @arg min minimum value
+     * @arg max maximum value
+     */
+    void setRange(int min, int max);
+
+    /**
+     * Sets the amount of the single step
+     * i.e how much the slider will move when the user press an arrow button
+     * @arg val
+     */
+    void setSingleStep(int val);
+
+    /**
+     * @return the amount of the single step
+     */
+    int singleStep();
+
+    /**
+     * Sets the amount the slider will scroll when the user press page up or page down
+     * @arg val
+     */
+    void setPageStep(int val);
+
+    /**
+     * @return the amount of the page step
+     */
+    int pageStep();
+
+    /**
+     * Sets the current value for the ScrollBar
+     * @arg value must be minimum() <= value <= maximum()
+     */
+    void setValue(int val);
+
+    /**
+     * @return the current scrollbar value
+     */
+    int value() const;
+
+    /**
+     * @return the minimum value bound of this ScrollBar
+     */
+    int minimum() const;
+
+    /**
+     * @return the maximum value bound of this ScrollBar
+     */
+    int maximum() const;
+
+    /**
+     * Sets the stylesheet used to control the visual display of this ScrollBar
+     *
+     * @arg stylesheet a CSS string
+     */
+    void setStyleSheet(const QString &stylesheet);
+
+    /**
+     * @return the stylesheet currently used with this widget
+     */
+    QString styleSheet();
+
+    /**
+     * @return the native widget wrapped by this ScrollBar
+     */
+    QScrollBar *nativeWidget() const;
+};
+
+}
+
+#endif
--- plasma/applet.cpp	
+++ plasma/applet.cpp	
@@ -76,6 +76,7 @@
 #include "plasma/view.h"
 #include "plasma/widgets/label.h"
 #include "plasma/widgets/pushbutton.h"
+#include "wallpaper.h"
 
 //#define DYNAMIC_SHADOWS
 namespace Plasma
@@ -351,6 +352,11 @@
     q->destroy();
 }
 
+void AppletPrivate::updateRect(const QRectF& rect)
+{
+    q->update(rect);
+}
+
 void AppletPrivate::cleanUpAndDelete()
 {
     //kDebug() << "???????????????? DESTROYING APPLET" << name() << " ???????????????????????????";
@@ -411,13 +417,23 @@
         return 0;
     }
 
+    QGraphicsView *found = 0;
+    QGraphicsView *possibleFind = 0;
+    //kDebug() << "looking through" << scene()->views().count() << "views";
     foreach (QGraphicsView *view, scene()->views()) {
+        //kDebug() << "     checking" << view << view->sceneRect() << "against" << sceneBoundingRect() << scenePos();
         if (view->sceneRect().intersects(sceneBoundingRect()) ||
             view->sceneRect().contains(scenePos())) {
-            return view;
+            //kDebug() << "     found something!" << view->isActiveWindow();
+            if (view->isActiveWindow()) {
+                found = view;
+            } else {
+                possibleFind = view;
+            }
         }
     }
-    return 0;
+
+    return found ? found : possibleFind;
 }
 
 QRectF Applet::mapFromView(const QGraphicsView *view, const QRect &rect) const
@@ -434,55 +450,7 @@
 
 QPoint Applet::popupPosition(const QSize &s) const
 {
-    QGraphicsView *v = view();
-    Q_ASSERT(v);
-
-    QPoint pos = v->mapFromScene(scenePos());
-    pos = v->mapToGlobal(pos);
-    //kDebug() << "==> position is" << scenePos() << v->mapFromScene(scenePos()) << pos;
-    Plasma::View *pv = dynamic_cast<Plasma::View *>(v);
-
-    Plasma::Location loc = Floating;
-    if (pv) {
-        loc = pv->containment()->location();
-    }
-
-    switch (loc) {
-    case BottomEdge:
-        pos = QPoint(pos.x(), pos.y() - s.height());
-        break;
-    case TopEdge:
-        pos = QPoint(pos.x(), pos.y() + (int)size().height());
-        break;
-    case LeftEdge:
-        pos = QPoint(pos.x() + (int)size().width(), pos.y());
-        break;
-    case RightEdge:
-        pos = QPoint(pos.x() - s.width(), pos.y());
-        break;
-    default:
-        if (pos.y() - s.height() > 0) {
-             pos = QPoint(pos.x(), pos.y() - s.height());
-        } else {
-             pos = QPoint(pos.x(), pos.y() + (int)size().height());
-        }
-    }
-
-    //are we out of screen?
-
-    QRect screenRect = QApplication::desktop()->screenGeometry(pv ? pv->containment()->screen() : -1);
-    //kDebug() << "==> rect for" << (pv ? pv->containment()->screen() : -1) << "is" << screenRect;
-
-    if (pos.rx() + s.width() > screenRect.right()) {
-        pos.rx() -= ((pos.rx() + s.width()) - screenRect.right());
-    }
-
-    if (pos.ry() + s.height() > screenRect.bottom()) {
-        pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom());
-    }
-    pos.rx() = qMax(0, pos.rx());
-
-    return pos;
+    return Plasma::popupPosition(this, s);
 }
 
 void Applet::updateConstraints(Plasma::Constraints constraints)
@@ -673,6 +641,9 @@
 
 void Applet::paintWindowFrame(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
 {
+    Q_UNUSED( painter );
+    Q_UNUSED( option );
+    Q_UNUSED( widget );
     //Here come the code for the window frame
     //kDebug() << windowFrameGeometry();
     //painter->drawRoundedRect(windowFrameGeometry(), 5, 5);
@@ -925,10 +896,15 @@
         if (widget && isContainment()) {
             // note that the widget we get is actually the viewport of the view, not the view itself
             View* v = qobject_cast<Plasma::View*>(widget->parent());
+
             if (!v || v->isWallpaperEnabled()) {
+                Containment* c = qobject_cast<Plasma::Containment*>(this);
+                if (c && c->drawWallpaper() && c->wallpaper()) {
+                    c->wallpaper()->paint(p, contentsRect);
+                }
+
                 Containment::StyleOption coption(*option);
                 coption.view = v;
-
                 paintInterface(p, &coption, contentsRect);
             }
 
@@ -1094,7 +1070,7 @@
     //TODO respect security when it's implemented (4.2)
     QAction *configAction = d->actions.action("configure");
     if (hasInterface) {
-        if (! configAction) { //should be always true
+        if (!configAction) { //should be always true
             configAction = new QAction(i18n("%1 Settings", name()), this);
             configAction->setIcon(KIcon("configure"));
             configAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); //don't clash with other views
--- plasma/private/tooltip_p.h	
+++ plasma/private/tooltip_p.h	
@@ -0,0 +1,64 @@
+/*
+ *   Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef PLASMA_TOOLTIP_P_H
+#define PLASMA_TOOLTIP_P_H
+
+#include <QWidget> // base class
+
+#include <plasma/tooltipmanager.h> //ToolTipContent struct
+
+namespace Plasma {
+
+class ToolTipPrivate;
+
+class ToolTip : public QWidget
+{
+    Q_OBJECT
+
+public:
+    ToolTip(QObject *source);
+    ~ToolTip();
+
+    void updateTheme();
+    void setContent(const ToolTipManager::ToolTipContent &data);
+    void prepareShowing(bool cueUpdate);
+    void setActivated(bool value);
+    bool isActivated();
+
+protected:
+    void showEvent(QShowEvent *);
+    void hideEvent(QHideEvent *);
+    void mouseReleaseEvent(QMouseEvent *);
+
+    void resizeEvent(QResizeEvent *);
+    void paintEvent(QPaintEvent *);
+
+private Q_SLOTS:
+    void sourceDestroyed();
+
+private:
+    ToolTipPrivate * const d;
+};
+
+} // namespace Plasma
+
+#endif // PLASMA_TOOLTIP_P_H
+
--- plasma/private/windowpreview.cpp	
+++ plasma/private/windowpreview.cpp	
@@ -0,0 +1,126 @@
+/*
+ *   Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "windowpreview_p.h"
+
+#include <KWindowSystem>
+
+#ifdef Q_WS_X11
+#include <QX11Info>
+
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#endif
+
+
+namespace Plasma {
+
+bool WindowPreview::previewsAvailable() // static
+{
+    if (!KWindowSystem::compositingActive()) {
+        return false;
+    }
+#ifdef Q_WS_X11
+    // hackish way to find out if KWin has the effect enabled,
+    // TODO provide proper support
+    Display* dpy = QX11Info::display();
+    Atom atom = XInternAtom(dpy, "_KDE_WINDOW_PREVIEW", False);
+    int cnt;
+    Atom* list = XListProperties(dpy, DefaultRootWindow( dpy ), &cnt);
+    if (list != NULL) {
+        bool ret = ( qFind(list, list + cnt, atom) != list + cnt );
+        XFree(list);
+        return ret;
+    }
+#endif
+    return false;
+}
+
+
+WindowPreview::WindowPreview(QWidget *parent)
+    : QWidget(parent)
+{
+}
+
+void WindowPreview::setWindowId(WId w)
+{
+    if (!previewsAvailable()) {
+        id = 0;
+        return;
+    }
+    id = w;
+    readWindowSize();
+}
+
+QSize WindowPreview::sizeHint() const
+{
+    if (id == 0) {
+        return QSize();
+    }
+    if (!windowSize.isValid()) {
+        readWindowSize();
+    }
+    QSize s = windowSize;
+    s.scale(200, 150, Qt::KeepAspectRatio);
+    return s;
+}
+
+void WindowPreview::readWindowSize() const
+{
+#ifdef Q_WS_X11
+    Window r;
+    int x, y;
+    unsigned int w, h, b, d;
+    if (XGetGeometry(QX11Info::display(), id, &r, &x, &y, &w, &h, &b, &d)) {
+        windowSize = QSize( w, h );
+    } else {
+        windowSize = QSize();
+    }
+#else
+    windowSize = QSize();
+#endif
+}
+
+void WindowPreview::setInfo()
+{
+#ifdef Q_WS_X11
+    Display *dpy = QX11Info::display();
+    Atom atom = XInternAtom(dpy, "_KDE_WINDOW_PREVIEW", False);
+    if (id == 0) {
+        XDeleteProperty(dpy, parentWidget()->winId(), atom);
+        return;
+    }
+    if (!windowSize.isValid()) {
+        readWindowSize();
+    }
+    if (!windowSize.isValid()) {
+        XDeleteProperty(dpy, parentWidget()->winId(), atom);
+        return;
+    }
+    Q_ASSERT( parentWidget()->isWindow()); // parent must be toplevel
+    long data[] = { 1, 5, id, x(), y(), width(), height() };
+    XChangeProperty(dpy, parentWidget()->winId(), atom, atom, 32, PropModeReplace,
+        reinterpret_cast< unsigned char* >( data ), sizeof( data ) / sizeof( data[ 0 ] ));
+#endif
+}
+
+} // namespace Plasma
+
+#include "windowpreview_p.moc"
--- plasma/private/tooltip.cpp	
+++ plasma/private/tooltip.cpp	
@@ -0,0 +1,199 @@
+/*
+ *   Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "tooltip_p.h"
+#include "windowpreview_p.h"
+
+#include <QBitmap>
+#include <QGridLayout>
+#include <QLabel>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QPalette>
+
+#include <KDebug>
+#include <KGlobal>
+
+#include <plasma/plasma.h>
+#include <plasma/theme.h>
+#include <plasma/panelsvg.h>
+
+namespace Plasma {
+
+class ToolTipPrivate
+{
+    public:
+        ToolTipPrivate(QObject *s)
+        : label(0)
+        , imageLabel(0)
+        , preview(0)
+        , windowToPreview(0)
+        , source(s)
+        , isActivated(true)
+    { }
+
+    QLabel *label;
+    QLabel *imageLabel;
+    WindowPreview *preview;
+    WId windowToPreview;
+    PanelSvg *background;
+    QObject *source;
+    bool isActivated;
+};
+
+void ToolTip::showEvent(QShowEvent *e)
+{
+    QWidget::showEvent(e);
+    d->preview->setInfo();
+}
+
+void ToolTip::hideEvent(QHideEvent *e)
+{
+    QWidget::hideEvent(e);
+    if (d->source) {
+        QMetaObject::invokeMethod(d->source, "toolTipHidden");
+    }
+}
+
+void ToolTip::mouseReleaseEvent(QMouseEvent* event)
+{
+    if (rect().contains(event->pos())) {
+        hide();
+    }
+}
+
+ToolTip::ToolTip(QObject *source)
+    : QWidget(0)
+    , d(new ToolTipPrivate(source))
+{
+    if (source) {
+        connect(source, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed()));
+    }
+
+    setWindowFlags(Qt::ToolTip);
+    QGridLayout *l = new QGridLayout;
+    d->preview = new WindowPreview(this);
+    d->label = new QLabel(this);
+    d->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+    d->label->setWordWrap(true);
+    d->imageLabel = new QLabel(this);
+    d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+
+    d->background = new PanelSvg(this);
+    connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(update()));
+
+    l->addWidget(d->preview, 0, 0, 1, 2);
+    l->addWidget(d->imageLabel, 1, 0);
+    l->addWidget(d->label, 1, 1);
+    setLayout(l);
+}
+
+ToolTip::~ToolTip()
+{
+    delete d;
+}
+
+void ToolTip::setContent(const ToolTipManager::ToolTipContent &data)
+{
+    //reset our size
+    d->label->setText("<qt><b>" + data.mainText + "</b><br>" + data.subText + "</qt>");
+    d->imageLabel->setPixmap(data.image);
+    d->windowToPreview = data.windowToPreview;
+    d->preview->setWindowId( d->windowToPreview );
+
+    if (isVisible()) {
+        resize(sizeHint());
+    }
+}
+
+void ToolTip::prepareShowing(bool cueUpdate)
+{
+    if (cueUpdate && d->source) {
+        QMetaObject::invokeMethod(d->source, "toolTipAboutToShow");
+    }
+
+    if (d->windowToPreview != 0) {
+        // show/hide the preview area
+        d->preview->show();
+    } else {
+        d->preview->hide();
+    }
+
+    layout()->activate();
+    resize(sizeHint());
+}
+
+void ToolTip::setActivated(bool value)
+{
+    d->isActivated = value;
+}
+
+bool ToolTip::isActivated()
+{
+    return d->isActivated;
+}
+
+void ToolTip::resizeEvent(QResizeEvent *e)
+{
+    QWidget::resizeEvent(e);
+    d->background->resizePanel(size());
+
+    setMask(d->background->mask());
+}
+
+void ToolTip::paintEvent(QPaintEvent *e)
+{
+    QPainter painter(this);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setClipRect(e->rect());
+    painter.setCompositionMode(QPainter::CompositionMode_Source );
+    painter.fillRect(rect(), Qt::transparent);
+
+    d->background->paintPanel(&painter);
+}
+
+void ToolTip::sourceDestroyed()
+{
+    d->source = 0;
+}
+
+void ToolTip::updateTheme()
+{
+    d->background->setImagePath("widgets/tooltip");
+    d->background->setEnabledBorders(PanelSvg::AllBorders);
+
+    const int topHeight = d->background->marginSize(Plasma::TopMargin);
+    const int leftWidth = d->background->marginSize(Plasma::LeftMargin);
+    const int rightWidth = d->background->marginSize(Plasma::RightMargin);
+    const int bottomHeight = d->background->marginSize(Plasma::BottomMargin);
+    setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
+
+    // Make the tooltip use Plasma's colorscheme
+    QPalette plasmaPalette = QPalette();
+    plasmaPalette.setColor(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
+    plasmaPalette.setColor(QPalette::WindowText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
+    setAutoFillBackground(true);
+    setPalette(plasmaPalette);
+}
+
+
+} // namespace Plasma
+
+#include "tooltip_p.moc"
--- plasma/private/windowpreview_p.h	
+++ plasma/private/windowpreview_p.h	
@@ -0,0 +1,59 @@
+/*
+ *   Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef PLASMA_WINDOWPREVIEW_P_H
+#define PLASMA_WINDOWPREVIEW_P_H
+
+#include <QWidget> // base class
+#include <QSize> // stack allocated
+
+namespace Plasma {
+
+/**
+ * @internal
+ *
+ * A widget which reserves area for window preview and sets hints on the toplevel
+ * tooltip widget that tells KWin to render the preview in this area. This depends
+ * on KWin's TaskbarThumbnail compositing effect (which is automaticaly detected).
+ */
+class WindowPreview : public QWidget
+{
+    Q_OBJECT
+
+public:
+    static bool previewsAvailable();
+
+    WindowPreview(QWidget *parent = 0);
+
+    void setWindowId(WId w);
+    void setInfo();
+    virtual QSize sizeHint() const;
+
+private:
+    void readWindowSize() const;
+
+    WId id;
+    mutable QSize windowSize;
+};
+
+} // namespace Plasma
+
+#endif // PLASMA_WINDOWPREVIEW_P_H
+
--- plasma/containment_p.h	
+++ plasma/containment_p.h	
@@ -38,10 +38,13 @@
           formFactor(Planar),
           location(Floating),
           focusedApplet(0),
+          wallpaper(0),
           screen(-1), // no screen
           toolBox(0),
           type(Containment::NoContainmentType),
-          positioning(false)
+          positioning(false),
+          drawWallpaper(true),
+          showToolBox(true)
     {
     }
 
@@ -71,6 +74,7 @@
     void containmentAppletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim);
     void zoomIn();
     void zoomOut();
+    bool showContextMenu(const QPointF &point, const QPoint &screenPos, bool includeApplet);
 
     /**
      * Locks or unlocks plasma's applets.
@@ -95,11 +99,14 @@
     Location location;
     Applet::List applets;
     Applet *focusedApplet;
+    Plasma::Wallpaper *wallpaper;
     QMap<Applet*, AppletHandle*> handles;
     int screen;
     ToolBox *toolBox;
     Containment::Type type;
     bool positioning;
+    bool drawWallpaper;
+    bool showToolBox;
 };
 
 } // Plasma namespace
--- plasma/view.cpp	
+++ plasma/view.cpp	
@@ -25,6 +25,7 @@
 
 #include "corona.h"
 #include "containment.h"
+#include "wallpaper.h"
 
 using namespace Plasma;
 
@@ -107,20 +108,24 @@
     : QGraphicsView(parent),
       d(new ViewPrivate(this, 0))
 {
-    Q_ASSERT(containment);
     d->initGraphicsView();
-    setScene(containment->scene());
-    setContainment(containment);
+
+    if (containment) {
+        setScene(containment->scene());
+        setContainment(containment);
+    }
 }
 
 View::View(Containment *containment, int viewId, QWidget *parent)
     : QGraphicsView(parent),
       d(new ViewPrivate(this, viewId))
 {
-    Q_ASSERT(containment);
     d->initGraphicsView();
-    setScene(containment->scene());
-    setContainment(containment);
+
+    if (containment) {
+        setScene(containment->scene());
+        setContainment(containment);
+    }
 }
 
 
@@ -198,6 +203,8 @@
     int screen = -1;
     if (oldContainment) {
         screen = d->containment->screen();
+    } else {
+        setScene(containment->scene());
     }
 
     d->containment = containment;
@@ -237,6 +244,44 @@
     return d->containment;
 }
 
+Containment* View::swapContainment(const QString& name, const QVariantList& args)
+{
+    Containment *old = d->containment;
+    Plasma::Corona* corona = old->corona();
+    Plasma::Containment *c = corona->addContainment(name, args);
+    if (c) {
+        KConfigGroup oldConfig = old->config();
+        KConfigGroup newConfig = c->config();
+
+        // ensure that the old containments configuration is up to date
+        old->save(oldConfig);
+
+        // set our containment to the new one
+        setContainment(c);
+
+        // Copy configuration to new containment
+        oldConfig.copyTo(&newConfig);
+
+        // load the configuration of the old containment into the new one
+        c->restore(newConfig);
+        foreach(Applet* applet, c->applets()) {
+            applet->init();
+            // We have to flush the applet constraints manually
+            applet->flushPendingConstraintsEvents();
+        }
+
+        // destroy the old one
+        old->destroy(false);
+
+        // and now save the config
+        c->save(newConfig);
+        corona->requestConfigSync();
+
+        return c;
+    }
+    return old;
+}
+
 KConfigGroup View::config() const
 {
     KConfigGroup views(KGlobal::config(), "PlasmaViews");
--- plasma/panelsvg.cpp	
+++ plasma/panelsvg.cpp	
@@ -37,16 +37,14 @@
     PanelData()
       : enabledBorders(PanelSvg::AllBorders),
         cachedBackground(0),
-        panelSize(-1,-1),
-        contentAtOrigin(false)
+        panelSize(-1,-1)
     {
     }
 
     PanelData(const PanelData &other)
       : enabledBorders(other.enabledBorders),
         cachedBackground(0),
-        panelSize(other.panelSize),
-        contentAtOrigin(other.contentAtOrigin)
+        panelSize(other.panelSize)
     {
     }
 
@@ -64,13 +62,18 @@
     int leftWidth;
     int rightWidth;
     int bottomHeight;
+    
+    //margins, are equal to the measures by default
+    int topMargin;
+    int leftMargin;
+    int rightMargin;
+    int bottomMargin;
 
     //size of the svg where the size of the "center"
     //element is contentWidth x contentHeight
     bool noBorderPadding : 1;
     bool stretchBorders : 1;
     bool tileCenter : 1;
-    bool contentAtOrigin : 1;
 };
 
 class PanelSvgPrivate
@@ -277,20 +280,20 @@
 
     switch (edge) {
     case Plasma::TopMargin:
-        return d->panels[d->prefix]->topHeight;
+        return d->panels[d->prefix]->topMargin;
     break;
 
     case Plasma::LeftMargin:
-        return d->panels[d->prefix]->leftWidth;
+        return d->panels[d->prefix]->leftMargin;
     break;
 
     case Plasma::RightMargin:
-        return d->panels[d->prefix]->rightWidth;
+        return d->panels[d->prefix]->rightMargin;
     break;
 
     //Plasma::BottomMargin
     default:
-        return d->panels[d->prefix]->bottomHeight;
+        return d->panels[d->prefix]->bottomMargin;
     break;
     }
 }
@@ -304,12 +307,26 @@
         return;
     }
 
-    top = panel->topHeight;
-    left = panel->leftWidth;
-    right = panel->rightWidth;
-    bottom = panel->bottomHeight;
+    top = panel->topMargin;
+    left = panel->leftMargin;
+    right = panel->rightMargin;
+    bottom = panel->bottomMargin;
 }
 
+QRectF PanelSvg::contentsRect() const
+{
+    QSizeF size(panelSize());
+
+    if (size.isValid()) {
+        QRectF rect(QPointF(0, 0), size);
+        PanelData *panel = d->panels[d->prefix];
+
+        return rect.adjusted(panel->leftMargin, panel->topMargin, -panel->rightMargin, -panel->bottomMargin);
+    } else {
+        return QRectF();
+    }
+}
+
 QBitmap PanelSvg::mask() const
 {
     PanelData *panel = d->panels[d->prefix];
@@ -359,22 +376,27 @@
         Q_ASSERT(panel->cachedBackground);
     }
 
-    //FIXME: this is redundant with generatebackground for now
-    bool origined = panel->contentAtOrigin;
-    const int topOffset = origined ? 0 - panel->topHeight : 0;
-    const int leftOffset = origined ? 0 - panel->leftWidth : 0;
+    painter->drawPixmap(rect, *(panel->cachedBackground), rect.translated(-pos.x(),-pos.y()));
+}
 
-    painter->drawPixmap(rect, *(panel->cachedBackground), rect.translated(-pos.x()-leftOffset,-pos.y()-topOffset));
+void PanelSvg::paintPanel(QPainter* painter, const QPointF& pos)
+{
+    PanelData *panel = d->panels[d->prefix];
+    if (!panel->cachedBackground) {
+        d->generateBackground(panel);
+        Q_ASSERT(panel->cachedBackground);
+    }
+
+    painter->drawPixmap(pos, *(panel->cachedBackground));
 }
 
 void PanelSvgPrivate::generateBackground(PanelData *panel)
 {
     //kDebug() << "generating background";
-    bool origined = panel->contentAtOrigin;
     const int topWidth = q->elementSize(prefix + "top").width();
     const int leftHeight = q->elementSize(prefix + "left").height();
-    const int topOffset = origined ? 0 - panel->topHeight : 0;
-    const int leftOffset = origined ? 0 - panel->leftWidth : 0;
+    const int topOffset = 0;
+    const int leftOffset = 0;
 
     if (panel->cachedBackground) {
         return;
@@ -400,14 +422,7 @@
     p.setCompositionMode(QPainter::CompositionMode_Source);
     p.setRenderHint(QPainter::SmoothPixmapTransform);
 
-    if (origined) {
-        p.translate(panel->leftWidth, panel->topHeight);
-    }
 
-    //FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image.
-    //       the transparent border around the svg seems to vary in size depending on the size of the svg and as a result increasing the
-    //       svg image by 2 all around didn't resolve the issue. For now it resizes based on the border size.
-
     //if we must stretch the center or the borders we compute how much we will have to stretch
     //the svg to get the desired element sizes
     QSizeF  scaledContentSize(0,0);
@@ -449,18 +464,14 @@
 
     // Corners
     if (q->hasElement(prefix + "top") && panel->enabledBorders & PanelSvg::TopBorder) {
-        if (!origined) {
-            contentTop = panel->topHeight;
-            bottomOffset += panel->topHeight;
-        }
+        contentTop = panel->topHeight;
+        bottomOffset += panel->topHeight;
 
         if (q->hasElement(prefix + "topleft") && panel->enabledBorders & PanelSvg::LeftBorder) {
             q->paint(&p, QRect(leftOffset, topOffset, panel->leftWidth, panel->topHeight), prefix + "topleft");
 
-            if (!origined) {
-                contentLeft = panel->leftWidth;
-                rightOffset = contentWidth + panel->leftWidth;
-            }
+            contentLeft = panel->leftWidth;
+            rightOffset = contentWidth + panel->leftWidth;
         }
 
         if (q->hasElement(prefix + "topright") && panel->enabledBorders & PanelSvg::RightBorder) {
@@ -472,10 +483,8 @@
         if (q->hasElement(prefix + "bottomleft") && panel->enabledBorders & PanelSvg::LeftBorder) {
             q->paint(&p, QRect(leftOffset, bottomOffset, panel->leftWidth, panel->bottomHeight), prefix + "bottomleft");
 
-            if (!origined) {
-                contentLeft = panel->leftWidth;
-                rightOffset = contentWidth + panel->leftWidth;
-            }
+            contentLeft = panel->leftWidth;
+            rightOffset = contentWidth + panel->leftWidth;
         }
 
         if (q->hasElement(prefix + "bottomright") && panel->enabledBorders & PanelSvg::RightBorder) {
@@ -575,26 +584,50 @@
     q->Svg::resize();
     if (panel->enabledBorders & PanelSvg::TopBorder) {
         panel->topHeight = q->elementSize(prefix + "top").height();
+        
+        if (q->hasElement(prefix + "hint-top-margin")) {
+            panel->topMargin = q->elementSize(prefix + "hint-top-margin").height();
+        } else {
+            panel->topMargin = panel->topHeight;
+        }
     } else {
-        panel->topHeight = 0;
+        panel->topMargin = panel->topHeight = 0;
     }
 
     if (panel->enabledBorders & PanelSvg::LeftBorder) {
         panel->leftWidth = q->elementSize(prefix + "left").width();
+        
+        if (q->hasElement(prefix + "hint-left-margin")) {
+            panel->leftMargin = q->elementSize(prefix + "hint-left-margin").height();
+        } else {
+            panel->leftMargin = panel->leftWidth;
+        }
     } else {
-        panel->leftWidth = 0;
+        panel->leftMargin = panel->leftWidth = 0;
     }
 
     if (panel->enabledBorders & PanelSvg::RightBorder) {
         panel->rightWidth = q->elementSize(prefix + "right").width();
+        
+        if (q->hasElement(prefix + "hint-right-margin")) {
+            panel->rightMargin = q->elementSize(prefix + "hint-right-margin").height();
+        } else {
+            panel->rightMargin = panel->rightWidth;
+        }
     } else {
-        panel->rightWidth = 0;
+        panel->rightMargin = panel->rightWidth = 0;
     }
 
     if (panel->enabledBorders & PanelSvg::BottomBorder) {
         panel->bottomHeight = q->elementSize(prefix + "bottom").height();
+        
+        if (q->hasElement(prefix + "hint-bottom-margin")) {
+            panel->bottomMargin = q->elementSize(prefix + "hint-bottom-margin").height();
+        } else {
+            panel->bottomMargin = panel->bottomHeight;
+        }
     } else {
-        panel->bottomHeight = 0;
+        panel->bottomMargin = panel->bottomHeight = 0;
     }
 
     //since it's rectangular, topWidth and bottomWidth must be the same
--- plasma/tests/packagemetadatatest.desktop	
+++ plasma/tests/packagemetadatatest.desktop	
@@ -81,8 +81,8 @@
 Comment[ro]=Un fișier birou de test  pentru a verifica clasa PackageMetaData.
 Comment[se]=.desktop-fiilla mainna geahččala PackageMeta-luohká.
 Comment[sl]=Namizna datoteka za test razreda PackageMetaData.
-Comment[sr]=Пробни фајл површи за класу PackageMetaData.
-Comment[sr@latin]=Probni fajl površi za klasu PackageMetaData.
+Comment[sr]=Пробни .десктоп фајл за класу PackageMetaData.
+Comment[sr@latin]=Probni .desktop fajl za klasu PackageMetaData.
 Comment[sv]=En skrivbordsfil för att testa klassen PackageMetaData.
 Comment[th]=แฟ้มทดสอบพื้นที่ทำงาน สำหรับทดสอบคลาสข้อมูลกำกับแพ็กเกจ
 Comment[tr]=PackageMetaData sınıfını test etmek için bir desktop dosyası
--- plasma/tests/testengine/plasma-dataengine-testengine.desktop	
+++ plasma/tests/testengine/plasma-dataengine-testengine.desktop	
@@ -26,7 +26,7 @@
 Name[ml]=ടെസ്റ്റ് ഡേറ്റാ എഞ്ചിന്‍
 Name[mr]=चाचणी माहिती इंजिन
 Name[nb]=Testdata-motor
-Name[nds]=Test-Hanteerkarn
+Name[nds]=Test-Datenkarn
 Name[nl]=Test (gegevensengine)
 Name[nn]=Testdatamotor
 Name[pa]=ਟੈਸਟ ਡਾਟਾ ਇੰਜਣ
@@ -35,8 +35,8 @@
 Name[pt_BR]=Mecanismo de dados de teste
 Name[ro]=Test motor de date
 Name[sl]=Preizkusni pogon s podatki
-Name[sr]=пробни мотор података
-Name[sr@latin]=probni motor podataka
+Name[sr]=пробни датомотор података
+Name[sr@latin]=probni datomotor podataka
 Name[sv]=Testdatagränssnitt
 Name[th]=โปรแกรมข้อมูลสำหรับทดสอบ
 Name[tr]=Test Veri Motoru
--- plasma/containment.h	
+++ plasma/containment.h	
@@ -42,6 +42,7 @@
 class Package;
 class Corona;
 class View;
+class Wallpaper;
 class ContainmentPrivate;
 
 /**
@@ -117,6 +118,8 @@
          */
         Containment(QObject *parent, const QVariantList &args);
 
+        Containment(QObject *parent, const QVariantList &args, bool showToolBox);
+
         ~Containment();
 
         /**
@@ -276,6 +279,27 @@
          */
         void removeAssociatedWidget(QWidget *widget);
 
+        /**
+         * Return whether wallpaper is painted or not.
+         */
+        bool drawWallpaper();
+
+        /**
+         * Sets wallpaper plugin.
+         */
+        void setWallpaper(const QString &pluginName, const QString &action = QString());
+
+       /**
+         * Return wallpaper plugin.
+         */
+        Plasma::Wallpaper* wallpaper();
+
+        /**
+         * Shows the context menu for the containment directly, bypassing Applets
+         * altogether.
+         */
+        void showContextMenu(const QPointF &containmentPos, const QPoint &screenPos);
+
     Q_SIGNALS:
         /**
          * This signal is emitted when a new applet is created by the containment
@@ -328,6 +352,11 @@
          */
         void focusRequested(Plasma::Containment *containment);
 
+        /**
+         * Emitted when the user wants to configure/change containment.
+         */
+        void configureRequested();
+
     public Q_SLOTS:
         /**
          * Informs the Corona as to what position it is in. This is informational
@@ -367,6 +396,19 @@
          */
         void destroy();
 
+        /**
+         * Destroys this containment and all its applets (after a confirmation dialog);
+         * it will be removed nicely and deleted.
+         * Its configuration will also be deleted.
+         *
+         * @arg confirm whether or not confirmation from the user should be requested
+         */
+        void destroy(bool confirm);
+
+        /**
+         * @reimplemented from Plasma::Applet
+         */
+        void showConfigurationInterface();
     protected:
         /**
          * Sets the type of this containment.
@@ -374,6 +416,11 @@
         void setContainmentType(Containment::Type type);
 
         /**
+         * Sets whether wallpaper is painted or not.
+         */
+        void setDrawWallpaper(bool drawWallpaper);
+
+        /**
          * Called when the contents of the containment should be saved. By default this saves
          * all loaded Applets
          *
@@ -389,11 +436,14 @@
          */
         virtual void restoreContents(KConfigGroup &group);
 
-
+        void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+        void mousePressEvent(QGraphicsSceneMouseEvent *event);
+        void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
         void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
         void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
         void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
         void keyPressEvent(QKeyEvent *event);
+        void wheelEvent(QGraphicsSceneWheelEvent *event);
         bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
         QVariant itemChange(GraphicsItemChange change, const QVariant &value);
 
@@ -412,6 +462,11 @@
          */
         void dropEvent(QGraphicsSceneDragDropEvent *event);
 
+        /**
+         * @reimplemented from QGraphicsItem
+         */
+        void resizeEvent(QGraphicsSceneResizeEvent *event);
+
     private:
         Q_PRIVATE_SLOT(d, void appletDestroyed(QObject*))
         Q_PRIVATE_SLOT(d, void containmentAppletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim))
@@ -423,6 +478,7 @@
         Q_PRIVATE_SLOT(d, void toggleDesktopImmutability())
 
         friend class Applet;
+        friend class CoronaPrivate;
         friend class ContainmentPrivate;
         ContainmentPrivate* const d;
 };
--- plasma/CMakeLists.txt	
+++ plasma/CMakeLists.txt	
@@ -58,9 +58,16 @@
     svg.cpp
     theme.cpp
     toolbox.cpp
+    tooltipmanager.cpp
+    tooltipmanager.h
+    private/tooltip.cpp
+    private/tooltip_p.h
+    private/windowpreview.cpp
+    private/windowpreview_p.h
     uiloader.cpp
     version.cpp
     view.cpp
+    wallpaper.cpp
     widgets/checkbox.cpp
     widgets/combobox.cpp
     widgets/flash.cpp
@@ -71,6 +78,7 @@
     widgets/meter.cpp
     widgets/pushbutton.cpp
     widgets/radiobutton.cpp
+    widgets/scrollbar.cpp
     widgets/signalplotter.cpp
     widgets/textedit.cpp
     widgets/webcontent.cpp
@@ -144,8 +152,10 @@
     svg.h
     theme.h
     uiloader.h
+    tooltipmanager.h
     version.h
-    view.h)
+    view.h
+    wallpaper.h)
 
 if(QT_QTOPENGL_FOUND AND OPENGL_FOUND)
 set(plasma_LIB_INCLUDES
@@ -168,6 +178,7 @@
     widgets/meter.h
     widgets/pushbutton.h
     widgets/radiobutton.h
+    widgets/scrollbar.h
     widgets/signalplotter.h
     widgets/textedit.h
     widgets/webcontent.h
@@ -223,15 +234,18 @@
 includes/RunnerManager
 includes/RunnerScript
 includes/ScriptEngine
+includes/ScrollBar
 includes/Service
 includes/ServiceJob
 includes/SignalPlotter
 includes/Svg
 includes/TextEdit
+includes/ToolTipManager
 includes/Theme
 includes/UiLoader
 includes/View
 includes/Version
+includes/Wallpaper
 includes/WebContent
 DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/Plasma COMPONENT Devel)
 
@@ -249,6 +263,7 @@
    servicetypes/plasma-packagestructure.desktop
    servicetypes/plasma-runner.desktop
    servicetypes/plasma-scriptengine.desktop
+   servicetypes/plasma-wallpaper.desktop
    DESTINATION ${SERVICETYPES_INSTALL_DIR})
 
 install(FILES scripting/plasmoids.knsrc DESTINATION  ${CONFIG_INSTALL_DIR})
--- plasma/theme.cpp	
+++ plasma/theme.cpp	
@@ -50,7 +50,6 @@
 public:
     ThemePrivate(Theme *theme)
         : q(theme),
-          defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
           defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
           defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
           defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
@@ -61,6 +60,10 @@
           hasWallpapers(false)
     {
         generalFont = QApplication::font();
+
+        KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc");
+        KConfigGroup group = KConfigGroup(defaultconfig, "Defaults");
+        defaultWallpaperTheme = group.readEntry("wallpaper", DEFAULT_WALLPAPER_THEME);
     }
 
     KConfigGroup& config()
@@ -247,7 +250,10 @@
         cg = d->config();
     }
 
-    d->defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME);
+    KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc");
+    KConfigGroup group = KConfigGroup(defaultconfig, "Defaults");
+    d->defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", group.readEntry("wallpaper", DEFAULT_WALLPAPER_THEME));
+
     d->defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX);
     d->defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH);
     d->defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT);
@@ -342,6 +348,10 @@
         }
     }
 
+    if (!QFile::exists(fullPath)) {
+        fullPath = KStandardDirs::locate("wallpaper", d->defaultWallpaperTheme);
+    }
+
     return fullPath;
 }
 
--- plasma/containment.cpp	
+++ plasma/containment.cpp	
@@ -51,10 +51,14 @@
 #include "desktoptoolbox_p.h"
 #include "paneltoolbox_p.h"
 #include "svg.h"
+#include "wallpaper.h"
 
 namespace Plasma
 {
 
+static const char defaultWallpaper[] = "image";
+static const char defaultWallpaperMode[] = "SingleImage";
+
 Containment::StyleOption::StyleOption()
     : QStyleOptionGraphicsItem(),
       view(0)
@@ -102,6 +106,17 @@
     setBackgroundHints(NoBackground);
 }
 
+Containment::Containment(QObject* parent, const QVariantList& args, bool showToolBox)
+    : Applet(parent, args),
+      d(new ContainmentPrivate(this))
+{
+    // WARNING: do not access config() OR globalConfig() in this method!
+    //          that requires a scene, which is not available at this point
+    setPos(0, 0);
+    setBackgroundHints(NoBackground);
+    d->showToolBox=showToolBox;
+}
+
 Containment::~Containment()
 {
     delete d;
@@ -199,7 +214,21 @@
                 d->toolBox->addTool(this->action("lock widgets"));
             }
             d->toolBox->addTool(this->action("add sibling containment"));
+            if (hasConfigurationInterface()) {
+                // re-use the contianment's action.
+                QAction* configureContainment = this->action("configure");
+                if (configureContainment) {
+                    d->toolBox->addTool(this->action("configure"));
+                }
+            }
+
         }
+
+        //Set a default wallpaper the first time the containment is created,
+        //for instance from the toolbox by the user
+        if (d->drawWallpaper) {
+            setDrawWallpaper(true);
+        }
     }
 
     Applet::init();
@@ -245,9 +274,19 @@
     setScreen(group.readEntry("screen", d->screen));
 
     flushPendingConstraintsEvents();
-    //kDebug() << "Containment" << id() << "geometry is" << geometry() << "config'd with" << appletConfig.name();
     restoreContents(group);
     setImmutability((ImmutabilityType)group.readEntry("immutability", (int)Mutable));
+
+    setWallpaper(group.readEntry("wallpaperplugin", defaultWallpaper),
+                 group.readEntry("wallpaperpluginmode", defaultWallpaperMode));
+    /*
+    kDebug() << "Containment" << id() <<
+                "screen" << screen() <<
+                "geometry is" << geometry() <<
+                "wallpaper" << ((d->wallpaper) ? d->wallpaper->pluginName() : QString()) <<
+                "wallpaper mode" << wallpaperMode() <<
+                "config entries" << group.entryMap();
+    */
 }
 
 void Containment::save(KConfigGroup &g) const
@@ -262,6 +301,15 @@
     group.writeEntry("screen", d->screen);
     group.writeEntry("formfactor", (int)d->formFactor);
     group.writeEntry("location", (int)d->location);
+
+    if (d->wallpaper) {
+        group.writeEntry("wallpaperplugin", d->wallpaper->pluginName());
+        group.writeEntry("wallpaperpluginmode", d->wallpaper->renderingMode().name());
+        KConfigGroup wallpaperConfig(&group, "Wallpaper");
+        wallpaperConfig = KConfigGroup(&wallpaperConfig, d->wallpaper->pluginName());
+        d->wallpaper->save(wallpaperConfig);
+    }
+
     saveContents(group);
 }
 
@@ -321,7 +369,7 @@
         return;
     }
 
-    if ((type == DesktopContainment || type == PanelContainment)) {
+    if ((type == DesktopContainment || type == PanelContainment) && d->showToolBox) {
         d->createToolBox();
     }
 }
@@ -331,6 +379,61 @@
     return dynamic_cast<Corona*>(scene());
 }
 
+void Containment::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+    event->ignore();
+    if (d->wallpaper) {
+        QGraphicsItem* item = scene()->itemAt(event->scenePos());
+        if (item == this) {
+            d->wallpaper->mouseMoveEvent(event);
+        }
+    }
+
+    if (!event->isAccepted()) {
+        event->accept();
+        Applet::mouseMoveEvent(event);
+    }
+}
+
+void Containment::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    event->ignore();
+    if (d->wallpaper) {
+        QGraphicsItem* item = scene()->itemAt(event->scenePos());
+        if (item == this) {
+            d->wallpaper->mousePressEvent(event);
+        }
+    }
+
+    if (event->isAccepted()) {
+        setFocus(Qt::MouseFocusReason);
+    } else {
+        event->accept();
+        Applet::mousePressEvent(event);
+    }
+}
+
+void Containment::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    event->ignore();
+    if (d->wallpaper) {
+        QGraphicsItem* item = scene()->itemAt(event->scenePos());
+        if (item == this) {
+            d->wallpaper->mouseReleaseEvent(event);
+        }
+    }
+
+    if (!event->isAccepted()) {
+        event->accept();
+        Applet::mouseReleaseEvent(event);
+    }
+}
+
+void Containment::showContextMenu(const QPointF &containmentPos, const QPoint &screenPos)
+{
+    d->showContextMenu(mapToScene(containmentPos), screenPos, false);
+}
+
 void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
 {
     //kDebug() << "let's see if we manage to get a context menu here, huh";
@@ -339,14 +442,22 @@
         return;
     }
 
-    QPointF point = event->scenePos();
-    QGraphicsItem* item = scene()->itemAt(point);
-    if (item == this) {
-        item = 0;
+    if (!d->showContextMenu(event->scenePos(), event->screenPos(), true)) {
+        Applet::contextMenuEvent(event);
+    } else {
+        event->accept();
     }
+}
 
+bool ContainmentPrivate::showContextMenu(const QPointF &point, const QPoint &screenPos, bool includeApplet)
+{
     Applet* applet = 0;
 
+    QGraphicsItem* item = q->scene()->itemAt(point);
+    if (item == q) {
+        item = 0;
+    }
+
     while (item) {
         applet = qgraphicsitem_cast<Applet*>(item);
         if (applet && !applet->isContainment()) {
@@ -362,15 +473,18 @@
     //kDebug() << "context menu event " << (QObject*)applet;
     if (applet) {
         bool hasEntries = false;
+        QList<QAction*> actions;
 
-        QList<QAction*> actions = applet->contextualActions();
-        if (!actions.isEmpty()) {
-            foreach(QAction* action, actions) {
-                if (action) {
-                    desktopMenu.addAction(action);
+        if (includeApplet) {
+            actions = applet->contextualActions();
+            if (!actions.isEmpty()) {
+                foreach(QAction* action, actions) {
+                    if (action) {
+                        desktopMenu.addAction(action);
+                    }
                 }
+                hasEntries = true;
             }
-            hasEntries = true;
         }
 
         if (applet->hasConfigurationInterface()) {
@@ -381,7 +495,7 @@
             }
         }
 
-        QList<QAction*> containmentActions = contextualActions();
+        QList<QAction*> containmentActions = q->contextualActions();
         if (!containmentActions.isEmpty()) {
             if (hasEntries) {
                 desktopMenu.addSeparator();
@@ -391,7 +505,7 @@
             QMenu *containmentActionMenu = &desktopMenu;
 
             if (!actions.isEmpty() && containmentActions.count() > 2) {
-                containmentActionMenu = new KMenu(i18n("%1 Options", name()), &desktopMenu);
+                containmentActionMenu = new KMenu(i18n("%1 Options", q->name()), &desktopMenu);
                 desktopMenu.addMenu(containmentActionMenu);
             }
 
@@ -402,7 +516,7 @@
             }
         }
 
-        if (scene() && static_cast<Corona*>(scene())->immutability() == Mutable) {
+        if (static_cast<Corona*>(q->scene())->immutability() == Mutable) {
             if (hasEntries) {
                 desktopMenu.addSeparator();
             }
@@ -412,30 +526,28 @@
                 kDebug() << "no remove action!!!!!!!!";
                 closeApplet = new QAction(i18n("Remove this %1", applet->name()), &desktopMenu);
                 closeApplet->setIcon(KIcon("edit-delete"));
-                connect(closeApplet, SIGNAL(triggered(bool)), applet, SLOT(destroy()));
+                QObject::connect(closeApplet, SIGNAL(triggered(bool)), applet, SLOT(destroy()));
             }
             desktopMenu.addAction(closeApplet);
             hasEntries = true;
         }
 
         if (!hasEntries) {
-            Applet::contextMenuEvent(event);
             kDebug() << "no entries";
-            return;
+            return false;
         }
     } else {
-        if (!scene() || (static_cast<Corona*>(scene())->immutability() != Mutable && !KAuthorized::authorizeKAction("unlock_desktop"))) {
+        if (static_cast<Corona*>(q->scene())->immutability() != Mutable &&
+            !KAuthorized::authorizeKAction("unlock_desktop")) {
             //kDebug() << "immutability";
-            Applet::contextMenuEvent(event);
-            return;
+            return false;
         }
 
-        QList<QAction*> actions = contextualActions();
+        QList<QAction*> actions = q->contextualActions();
 
         if (actions.count() < 1) {
             //kDebug() << "no applet, but no actions";
-            Applet::contextMenuEvent(event);
-            return;
+            return false;
         }
 
         foreach (QAction* action, actions) {
@@ -445,9 +557,9 @@
         }
     }
 
-    event->accept();
-    //kDebug() << "executing at" << event->screenPos();
-    desktopMenu.exec(event->screenPos());
+    //kDebug() << "executing at" << screenPos;
+    desktopMenu.exec(screenPos);
+    return true;
 }
 
 void Containment::setFormFactor(FormFactor formFactor)
@@ -795,6 +907,14 @@
     }
 }
 
+void Containment::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+    Applet::resizeEvent(event);
+    if (d->wallpaper) {
+        d->wallpaper->setBoundingRect(boundingRect());
+    }
+}
+
 void Containment::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
 {
     //FIXME Qt4.4 check to see if this is still necessary to avoid unnecessary repaints
@@ -826,6 +946,42 @@
     }
 }
 
+void Containment::wheelEvent(QGraphicsSceneWheelEvent *event)
+{
+    if (d->wallpaper) {
+        QGraphicsItem* item = scene()->itemAt(event->scenePos());
+        if (item == this) {
+            event->ignore();
+            d->wallpaper->wheelEvent(event);
+
+            if (event->isAccepted()) {
+                return;
+            }
+
+            event->accept();
+        }
+    }
+
+    if (containmentType() == DesktopContainment) {
+        QGraphicsItem* item = scene()->itemAt(event->scenePos());
+        if (item == this) {
+            int numDesktops = KWindowSystem::numberOfDesktops();
+            int currentDesktop = KWindowSystem::currentDesktop();
+
+            if (event->delta() > 0) {
+                KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1);
+            } else {
+                KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1);
+            }
+
+            event->accept();
+            return;
+        }
+    }
+
+    Applet::wheelEvent(event);
+}
+
 bool Containment::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
 {
     Applet *applet = qgraphicsitem_cast<Applet*>(watched);
@@ -955,6 +1111,85 @@
     }
 }
 
+void Containment::setDrawWallpaper(bool drawWallpaper)
+{
+    d->drawWallpaper = drawWallpaper;
+    if (d->drawWallpaper) {
+        KConfigGroup cfg = config();
+        QString wallpaper = cfg.readEntry("wallpaperplugin", defaultWallpaper);
+        QString mode = cfg.readEntry("wallpaperpluginmode", defaultWallpaperMode);
+        setWallpaper(wallpaper, mode);
+    } else if (!d->drawWallpaper && d->wallpaper) {
+        delete d->wallpaper;
+        d->wallpaper = 0;
+    }
+}
+
+bool Containment::drawWallpaper()
+{
+    return d->drawWallpaper;
+}
+
+void Containment::setWallpaper(const QString &pluginName, const QString &mode)
+{
+    KConfigGroup cfg = config();
+    bool newPlugin = true;
+    bool newMode = true;
+
+    if (d->drawWallpaper) {
+        if (d->wallpaper) {
+            // we have a wallpaper, so let's decide whether we need to swap it out
+            if (d->wallpaper->pluginName() != pluginName) {
+                delete d->wallpaper;
+                d->wallpaper = 0;
+            } else {
+                // it's the same plugin, so let's save its state now so when
+                // we call restore later on we're safe
+                newMode = d->wallpaper->renderingMode().name() != mode;
+                newPlugin = false;
+            }
+        }
+
+        if (!pluginName.isEmpty() && !d->wallpaper) {
+            d->wallpaper = Plasma::Wallpaper::load(pluginName);
+        }
+
+        if (d->wallpaper) {
+            d->wallpaper->setBoundingRect(boundingRect());
+
+            KConfigGroup wallpaperConfig = KConfigGroup(&cfg, "Wallpaper");
+            wallpaperConfig = KConfigGroup(&wallpaperConfig, pluginName);
+            d->wallpaper->restore(wallpaperConfig, mode);
+
+            if (newPlugin) {
+                connect(d->wallpaper, SIGNAL(update(const QRectF&)),
+                        this, SLOT(updateRect(const QRectF&)));
+                cfg.writeEntry("wallpaperplugin", pluginName);
+            }
+
+            if (newMode) {
+                cfg.writeEntry("wallpaperpluginmode", mode);
+            }
+        }
+
+        update();
+    }
+
+    if (!d->wallpaper) {
+        cfg.deleteEntry("wallpaperplugin");
+        cfg.deleteEntry("wallpaperpluginmode");
+    }
+
+    if (newPlugin || newMode) {
+        emit configNeedsSaving();
+    }
+}
+
+Plasma::Wallpaper* Containment::wallpaper()
+{
+    return d->wallpaper;
+}
+
 KActionCollection& ContainmentPrivate::actions()
 {
     return static_cast<Applet*>(q)->d->actions;
@@ -1022,6 +1257,11 @@
 
 void Containment::destroy()
 {
+    destroy(true);
+}
+
+void Containment::destroy(bool confirm)
+{
     if (immutability() != Mutable) {
         return;
     }
@@ -1036,7 +1276,7 @@
         }
 
         //FIXME maybe that %1 should be the containment type not the name
-        if (KMessageBox::warningContinueCancel(view(), i18n("Do you really want to remove this %1?", name()),
+        if (!confirm || KMessageBox::warningContinueCancel(view(), i18n("Do you really want to remove this %1?", name()),
                     i18n("Remove %1", name()), KStandardGuiItem::remove()) == KMessageBox::Continue ) {
             //clearApplets();
             Applet::destroy();
@@ -1046,6 +1286,15 @@
     }
 }
 
+void Containment::showConfigurationInterface()
+{
+    if (isContainment()) {
+        emit configureRequested();
+    }
+    else {
+        Applet::showConfigurationInterface();
+    }
+}
 
 // Private class implementation
 
--- plasma/view.h	
+++ plasma/view.h	
@@ -119,6 +119,16 @@
     Containment* containment() const;
 
     /**
+     * Swap the containment for this view, which will also cause the view
+     * to track the geometry of the containment.
+     *
+     * @param name the plugin name for the new containment.
+     * @param args argument list to pass to the containment
+     */
+    Containment* swapContainment(const QString& name,
+                                 const QVariantList& args = QVariantList());
+
+    /**
      * Set whether or not the view should adjust its size when the associated
      * containment does.
      * @arg trackChanges true to syncronize the view's size with the containment's
--- plasma/corona.h	
+++ plasma/corona.h	
@@ -93,6 +93,11 @@
      */
     Containment* containmentForScreen(int screen) const;
 
+    /**
+     * SUSE-specific extension
+     **/
+    virtual bool loadDefaultApplets(Plasma::Containment* panel, bool askType=false);
+
 public Q_SLOTS:
     /**
      * Initializes the layout from a config file. This will first clear any existing
--- plasma/tooltipmanager.h	
+++ plasma/tooltipmanager.h	
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
+ * Copyright 2008 by Aaron Seigo <aseigo@kde.org>
+ * Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef PLASMA_TOOL_TIP_MANAGER_H
+#define PLASMA_TOOL_TIP_MANAGER_H
+
+//plasma
+#include <plasma/plasma.h>
+#include <plasma/plasma_export.h>
+
+namespace Plasma
+{
+
+class ToolTipManagerPrivate;
+class Applet;
+
+/**
+ * @class ToolTipManager plasma/tooltipmanager.h <Plasma/ToolTipManager>
+ *
+ * @short Manages tooltips for QGraphicsWidgets in Plasma
+ *
+ * If you want a widget to have a tooltip displayed when the mouse is hovered over
+ * it, you should do something like:
+ *
+ * @code
+ * // widget is a QGraphicsWidget*
+ * Plasma::ToolTipManager::ToolTipContent data;
+ * data.mainText = i18n("My Title");
+ * data.subText = i18n("This is a little tooltip");
+ * data.image = KIcon("some-icon").pixmap(IconSize(KIconLoader::Desktop));
+ * Plasma::ToolTipManager::self()->setToolTipContent(widget, data);
+ * @endcode
+ *
+ * Note that, since a Plasma::Applet is a QGraphicsWidget, you can use
+ * Plasma::ToolTipManager::self()->setToolTipContent(this, data); in the
+ * applet's init() method to set a tooltip for the whole applet.
+ *
+ * The tooltip will be registered automatically by setToolTipContent().  It will be
+ * automatically unregistered when the associated widget is deleted, freeing the
+ * memory used by the tooltip, but you can manually unregister it at any time by
+ * calling unregisterWidget().
+ *
+ * When a tooltip for a widget is about to be shown, the widget's toolTipAboutToShow slot will be
+ * invoked if it exists. Similarly, when a tooltip is hidden, the widget's toolTipHidden() slot
+ * will be invoked if it exists. This allows widgets to provide on-demand tooltip data.
+ */
+class PLASMA_EXPORT ToolTipManager  : public QObject
+{
+    Q_OBJECT
+public:
+
+    /**
+     * @struct ToolTipContent plasma/tooltipmanager.h <Plasma/ToolTipManager>
+     *
+     * This provides the content for a tooltip.
+     *
+     * Normally you will want to set at least the @p mainText and
+     * @p subText.
+     */
+    struct PLASMA_EXPORT ToolTipContent
+    {
+        /** Creates an empty ToolTipContent */
+        ToolTipContent();
+
+        /** @return true if all the fields are empty */
+        bool isEmpty() const;
+
+        /** Important information, e.g. the title */
+        QString mainText;
+        /** Elaborates on the @p mainText */
+        QString subText;
+        /** An icon to display */
+        QPixmap image;
+        /** Id of a window if you want to show a preview */
+        WId windowToPreview;
+    };
+
+    /**
+     * @return The singleton instance of the manager.
+     */
+    static ToolTipManager *self();
+
+    /**
+     * Default constructor.
+     *
+     * You should normall use self() instead.
+     */
+    explicit ToolTipManager(QObject* parent = 0);
+
+    /**
+     * Default destructor.
+     */
+    ~ToolTipManager();
+
+    /**
+     * Show the tooltip for a widget registered in the tooltip manager
+     *
+     * @param widget the widget for which the tooltip will be displayed
+     */
+    void showToolTip(QGraphicsWidget *widget);
+
+    /**
+     * Find out whether the tooltip for a given widget is currently being displayed.
+     *
+     * @param widget the widget to check the tooltip for
+     * @return true if the tooltip of the widget is currently displayed,
+     *         false if not
+     */
+    bool isWidgetToolTipDisplayed(QGraphicsWidget *widget);
+
+    /**
+     * Hides the currently showing tooltip after a short amount of time.
+     */
+    void delayedHideToolTip();
+
+    /**
+     * Hides the tooltip for a widget immediately.
+     *
+     * @param widget the widget to hide the tooltip for
+     */
+    void hideToolTip(QGraphicsWidget *widget);
+
+    /**
+     * Registers a widget with the tooltip manager.
+     *
+     * Note that setToolTipContent() will register the widget if it
+     * has not already been registered, and so you do not normally
+     * need to use the method.
+     *
+     * This is useful for creating tooltip content on demand.  You can
+     * register your widget with registerWidget(), then implement
+     * a slot named toolTipAboutToShow for the widget.  This will be
+     * called before the tooltip is shown, allowing you to set the
+     * data with setToolTipContent().
+     *
+     * If the widget also has a toolTipHidden slot, this will be called
+     * after the tooltip is hidden.
+     *
+     * @param widget the desired widget
+     */
+    void registerWidget(QGraphicsWidget *widget);
+
+    /**
+     * Unregisters a widget from the tooltip manager.
+     *
+     * This will free the memory used by the tooltip associated with the widget.
+     *
+     * @param widget the desired widget to delete
+     */
+    void unregisterWidget(QGraphicsWidget *widget);
+
+    /**
+     * Sets the content for the tooltip associated with a widget.
+     *
+     * Note that this will register the widget with the ToolTipManager if
+     * necessary, so there is usually no need to call registerWidget().
+     *
+     * @param widget the widget the tooltip should be associated with
+     * @param data   the content of the tooltip. If an empty ToolTipContent
+     *               is passed in, the tooltip content will be reset.
+     */
+    void setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data);
+
+    /**
+     * Clears the tooltip data associated with this widget, but keeps
+     * the widget registered.
+     */
+    void clearToolTipContent(QGraphicsWidget *widget);
+
+    /**
+     * Checks whether a widget has a tooltip associated with it.
+     *
+     * @param widget the widget to check for an associated tooltip
+     * @return true if the widget has a tooltip associated,
+     *         false if it does not
+     */
+    bool widgetHasToolTip(QGraphicsWidget *widget) const;
+
+    /**
+     *  Enable/or disable a Tooltip, this method is usefull is we want
+     *  to have a tooltip activated on demand.
+     *  @param widget the widget to change tooltip behaviour
+     *  @param enable if we need the tooltip or not
+     */
+    void setToolTipActivated(QGraphicsWidget *widget, bool enable);
+
+    /**
+     * Return true is the tooltip will be displayed, false otherwise
+     */
+    bool isToolTipActivated(QGraphicsWidget *widget);
+
+private:
+    friend class ToolTipManagerSingleton;
+    bool eventFilter(QObject *watched, QEvent *event);
+
+    ToolTipManagerPrivate* const d;
+    Q_PRIVATE_SLOT(d, void showToolTip())
+    Q_PRIVATE_SLOT(d, void resetShownState())
+    Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*))
+    Q_PRIVATE_SLOT(d, void themeUpdated())
+};
+
+} // namespace Plasma
+
+#endif // PLASMA_TOOL_TIP_MANAGER_H
--- plasma/wallpaper.h	
+++ plasma/wallpaper.h	
@@ -0,0 +1,234 @@
+/*
+ *   Copyright 2008 by Aaron Seigo <aseigo@kde.org>
+ *   Copyright 2008 by Petri Damsten <damu@iki.fi>
+
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, 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 Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef PLASMA_WALLPAPER_H
+#define PLASMA_WALLPAPER_H
+
+#include <KDE/KPluginInfo>
+
+#include <plasma/plasma.h>
+#include <plasma/version.h>
+
+namespace Plasma
+{
+class WallpaperPrivate;
+
+/**
+ * @short The base Wallpaper class
+ *
+ * "Wallpapers" are components that paint the background for Containments that
+ * do not provide their own background rendering.
+ *
+ * Wallpaper plugins are registered using .desktop files. These files should be
+ * named using the following naming scheme:
+ *
+ *     plasma-wallpaper-<pluginname>.desktop
+ *
+ * If a wallpaper plugin provides more than on mode (e.g. Single Image, Wallpaper)
+ * it should include a Actions= entry in the .desktop file, listing the possible
+ * actions. An actions group should be included to provide for translatable names.
+ */
+
+class PLASMA_EXPORT Wallpaper : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QRectF boundingRect READ boundingRect WRITE setBoundingRect)
+    Q_PROPERTY(QString name READ name)
+    Q_PROPERTY(QString pluginName READ pluginName)
+    Q_PROPERTY(QString icon READ icon)
+    Q_PROPERTY(KServiceAction renderingMode READ renderingMode)
+    Q_PROPERTY(QList<KServiceAction> listRenderingModes READ listRenderingModes)
+
+    public:
+        ~Wallpaper();
+
+        /**
+         * Returns a list of all known wallpapers.
+         *
+         * @return list of wallpapers
+         **/
+        static KPluginInfo::List listWallpaperInfo(const QString &formFactor = QString());
+
+        /**
+         * Attempts to load an wallpaper
+         *
+         * Returns a pointer to the wallpaper if successful.
+         * The caller takes responsibility for the wallpaper, including
+         * deleting it when no longer needed.
+         *
+         * @param name the plugin name, as returned by KPluginInfo::pluginName()
+         * @param args to send the wallpaper extra arguments
+         * @return a pointer to the loaded wallpaper, or 0 on load failure
+         **/
+        static Wallpaper* load(const QString &name, const QVariantList& args = QVariantList());
+
+        /**
+         * Attempts to load an wallpaper
+         *
+         * Returns a pointer to the wallpaper if successful.
+         * The caller takes responsibility for the wallpaper, including
+         * deleting it when no longer needed.
+         *
+         * @param info KPluginInfo object for the desired wallpaper
+         * @param args to send the wallpaper extra arguments
+         * @return a pointer to the loaded wallpaper, or 0 on load failure
+         **/
+        static Wallpaper* load(const KPluginInfo& info, const QVariantList& args = QVariantList());
+
+        /**
+         * Returns the user-visible name for the wallpaper, as specified in the
+         * .desktop file.
+         *
+         * @return the user-visible name for the wallpaper.
+         **/
+        QString name() const;
+
+        /**
+         * Returns the plugin name for the wallpaper
+         */
+        QString pluginName() const;
+
+        /**
+         * Returns the icon related to this wallpaper
+         **/
+        QString icon() const;
+
+        /**
+         * @return the currently active rendering mode
+         */
+        KServiceAction renderingMode() const;
+
+        /**
+         * Returns modes the wallpaper has, as specified in the
+         * .desktop file.
+         */
+        QList<KServiceAction> listRenderingModes() const;
+
+        /**
+         * Returns bounding rectangle
+         */
+        QRectF boundingRect() const;
+
+        /**
+         * Sets bounding rectangle
+         */
+        void setBoundingRect(const QRectF& boundingRect);
+
+       /**
+         * This method is called when the wallpaper should be painted.
+         *
+         * @param painter the QPainter to use to do the painting
+         * @param exposedRect the rect to paint within
+         **/
+        virtual void paint(QPainter *painter, const QRectF& exposedRect) = 0;
+
+        /**
+         * This method should be called once the wallpaper is loaded or mode is changed.
+         * @param config Config group to load settings
+         * @param mode One of the modes supported by the plugin,
+         *        or an empty string for the default mode.
+         * @see init
+         **/
+        void restore(const KConfigGroup &config, const QString &mode = QString());
+
+        /**
+         * This method is called when settings need to be saved.
+         * @param config Config group to save settings
+         **/
+        virtual void save(KConfigGroup &config);
+
+        /**
+         * Returns widget for configuration dialog.
+         */
+        virtual QWidget *createConfigurationInterface(QWidget *parent);
+
+        /**
+         * Mouse move event. To prevent further propagation of the event,
+         * the event must be accepted.
+         *
+         * @param event the mouse event object
+         */
+        virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+
+        /**
+         * Mouse press event. To prevent further propagation of the even,
+         * and to receive mouseMoveEvents, the event must be accepted.
+         *
+         * @param event the mouse event object
+         */
+        virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+
+        /**
+         * Mouse release event. To prevent further propagation of the event,
+         * the event must be accepted.
+         *
+         * @param event the mouse event object
+         */
+        virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+        /**
+         * Mouse wheel event. To prevent further propagation of the event,
+         * the event must be accepted.
+         *
+         * @param event the wheel event object
+         */
+        virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
+
+    Q_SIGNALS:
+        /**
+         * This signal indicates that wallpaper needs to be repainted.
+         */
+        void update(const QRectF &exposedArea);
+
+    protected:
+        /**
+         * This constructor is to be used with the plugin loading systems
+         * found in KPluginInfo and KService. The argument list is expected
+         * to have one element: the KService service ID for the desktop entry.
+         *
+         * @param parent a QObject parent; you probably want to pass in 0
+         * @param args a list of strings containing one entry: the service id
+         */
+        Wallpaper(QObject* parent, const QVariantList& args);
+
+        /**
+         * This method is called once the wallpaper is loaded or mode is changed.
+         * The mode can be retrieved using the @see renderMode() method.
+         * @param config Config group to load settings
+         * @param mode One of the modes supported by the plugin,
+         *        or an empty string for the default mode.
+         **/
+        virtual void init(const KConfigGroup &config);
+
+    private:
+        WallpaperPrivate* const d;
+};
+
+} // Plasma namespace
+
+/**
+ * Register an wallpaper when it is contained in a loadable module
+ */
+#define K_EXPORT_PLASMA_WALLPAPER(libname, classname) \
+K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \
+K_EXPORT_PLUGIN(factory("plasma_wallpaper_" #libname)) \
+K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)
+
+#endif // multiple inclusion guard
--- taskmanager/task.cpp	
+++ taskmanager/task.cpp	
@@ -28,7 +28,13 @@
 // Qt
 #include <QMimeData>
 #include <QTimer>
+#include <QApplication>
+#include <QDesktopWidget>
 
+#ifdef Q_WS_X11
+#include <QX11Info>
+#endif
+
 // KDE
 #include <KDebug>
 #include <KIconLoader>
@@ -73,6 +79,7 @@
     int lastHeight;
     bool lastResize;
     QPixmap lastIcon;
+    QIcon icon;
 
     double thumbSize;
     QPixmap thumb;
@@ -191,7 +198,8 @@
     }
 
     d->lastIcon = QPixmap();
-    emit iconChanged();
+    d->icon = QIcon();
+    emit changed(IconChanged);
 }
 
 void Task::refresh(unsigned int dirty)
@@ -201,20 +209,46 @@
         NET::WMState | NET::XAWMState | NET::WMDesktop | NET::WMVisibleName | NET::WMGeometry | NET::WMWindowType,
         NET::WM2AllowedActions);
 
-    if (dirty != NET::WMName || name != visibleName())
-    {
-        emit changed();
+    TaskChanges changes = TaskUnchanged;
+
+    if (name != visibleName()) {
+        changes |= NameChanged;
     }
+
+    if (dirty & NET::WMState || dirty & NET::XAWMState) {
+        changes |= StateChanged;
+    }
+
+    if (dirty & NET::WMDesktop) {
+        changes |= DesktopChanged;
+    }
+
+    if (dirty & NET::WMGeometry) {
+        changes |= GeometryChanged;
+    }
+
+    if (dirty & NET::WMWindowType) {
+        changes |= WindowTypeChanged;
+    }
+
+    if (dirty & NET::WM2AllowedActions) {
+        changes |= ActionsChanged;
+    }
+
+    if (changes != TaskUnchanged) {
+        emit changed(changes);
+    }
 }
 
 void Task::setActive(bool a)
 {
     d->active = a;
-    emit changed();
-    if ( a )
+    emit changed(StateChanged);
+    if (a) {
       emit activated();
-    else
+    } else {
       emit deactivated();
+    }
 }
 
 double Task::thumbnailSize() const { return d->thumbSize; }
@@ -357,7 +391,7 @@
     if (info.state() & NET::DemandsAttention)
     {
         d->transientsDemandingAttention.append(w);
-        emit changed();
+        emit changed(TransientsChanged);
     }
 }
 
@@ -397,7 +431,7 @@
     return d->info.name();
 }
 
-QString Task::className()
+QString Task::className() const
 {
     XClassHint hint;
     if(XGetClassHint(QX11Info::display(), d->win, &hint)) {
@@ -409,7 +443,7 @@
     return QString();
 }
 
-QString Task::classClass()
+QString Task::classClass() const
 {
     XClassHint hint;
     if(XGetClassHint(QX11Info::display(), d->win, &hint)) {
@@ -440,6 +474,22 @@
   return newIcon;
 }
 
+QIcon Task::icon()
+{
+    if ( !d->icon.isNull() )
+        return d->icon;
+
+    d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmall, KIconLoader::SizeSmall, false));
+    d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium, false));
+    d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeMedium, KIconLoader::SizeMedium, false));
+    d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeLarge, KIconLoader::SizeLarge, false));
+
+    return d->icon;
+}
+
+
+
+
 WindowList Task::transients() const
 {
     return d->transients;
--- taskmanager/taskmanager.h	
+++ taskmanager/taskmanager.h	
@@ -28,6 +28,7 @@
 // Own
 #include "startup.h"
 #include "task.h"
+#include <taskmanager/taskmanager_export.h>
 
 namespace TaskManager
 {
--- taskmanager/taskmanager_export.h	
+++ taskmanager/taskmanager_export.h	
@@ -0,0 +1,45 @@
+/*****************************************************************
+
+Copyright 2008 Aaron Seigo <aseigo@kde.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+
+#ifndef TASKMANAGER_EXPORT_H
+#define TASKMANAGER_EXPORT_H
+
+/* needed for TASKMANAGER_EXPORT and KDE_IMPORT macros */
+#include <kdemacros.h>
+
+#ifndef TASKMANAGER_EXPORT
+# if defined(MAKE_TASKMANAGER_LIB)
+   /* We are building this library */
+#  define TASKMANAGER_EXPORT KDE_EXPORT
+# else
+   /* We are using this library */
+#  define TASKMANAGER_EXPORT KDE_IMPORT
+# endif
+#endif
+
+# ifndef TASKMANAGER_EXPORT_DEPRECATED
+#  define TASKMANAGER_EXPORT_DEPRECATED KDE_DEPRECATED TASKMANAGER_EXPORT
+# endif
+
+#endif
--- taskmanager/task.h	
+++ taskmanager/task.h	
@@ -29,12 +29,16 @@
 #include <QtGui/QDrag>
 #include <QtGui/QPixmap>
 #include <QtGui/QWidget>
+#include <QtCore/QHash>
+#include <QtGui/QIcon>
 
 // KDE
-#include <ksharedptr.h>
-#include <kwindowsystem.h>
-#include <netwm.h>
+#include <KDE/KSharedPtr>
+#include <KDE/KWindowSystem>
+#include <KDE/NETWinInfo>
 
+#include <taskmanager/taskmanager_export.h>
+
 namespace TaskManager
 {
 
@@ -43,8 +47,21 @@
 class Task;
 typedef KSharedPtr<Task> TaskPtr;
 typedef QVector<TaskPtr> TaskList;
-typedef QMap<WId, TaskPtr> TaskDict;
+typedef QHash<WId, TaskPtr> TaskDict;
 
+enum TaskChange { TaskUnchanged = 0,
+                  NameChanged = 1,
+                  StateChanged = 2,
+                  DesktopChanged = 32,
+                  GeometryChanged = 64,
+                  WindowTypeChanged = 128,
+                  ActionsChanged = 256,
+                  TransientsChanged = 512,
+                  IconChanged = 1024,
+                  EverythingChanged = 0xffff
+                };
+Q_DECLARE_FLAGS(TaskChanges, TaskChange)
+
 /**
  * A dynamic interface to a task (main window).
  *
@@ -84,8 +101,8 @@
     QString visibleName() const;
     QString visibleNameWithState() const;
     QString name() const;
-    QString className();
-    QString classClass();
+    QString className() const;
+    QString classClass() const;
 
     /**
      * A list of the window ids of all transient windows (dialogs) associated
@@ -127,6 +144,11 @@
     QPixmap icon( int width, int height, bool allowResize = false );
 
     /**
+     * \return a QIcon for the task
+     */
+    QIcon icon();
+
+    /**
      * Returns true iff the windows with the specified ids should be grouped
      * together in the task list.
      */
@@ -388,14 +410,9 @@
     /**
      * Indicates that this task has changed in some way.
      */
-    void changed();
+    void changed(::TaskManager::TaskChanges change);
 
     /**
-     * Indicates that the icon for this task has changed.
-     */
-    void iconChanged();
-
-    /**
      * Indicates that this task is now the active task.
      */
     void activated();
--- taskmanager/CMakeLists.txt	
+++ taskmanager/CMakeLists.txt	
@@ -21,6 +21,6 @@
 set_target_properties(taskmanager PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
 install(TARGETS taskmanager ${INSTALL_TARGETS_DEFAULT_ARGS} )
 
-install( FILES task.h startup.h taskmanager.h DESTINATION ${INCLUDE_INSTALL_DIR}/taskmanager  COMPONENT Devel )
+install( FILES task.h startup.h taskmanager.h taskmanager_export.h DESTINATION ${INCLUDE_INSTALL_DIR}/taskmanager  COMPONENT Devel )
 
 
openSUSE Build Service is sponsored by