Index: desktop.h
===================================================================
--- desktop.h	(revision 1150824)
+++ desktop.h	(working copy)
@@ -31,26 +31,18 @@
 #include <KIcon>
 
 #include <Plasma/Containment>
-#include <Plasma/Animator>
 
 #include "desktoplayout.h"
 
 
 namespace Plasma
 {
+    class ToolButton;
+    class SvgWidget;
 }
 
-/*class Tool : public QObject, public QGraphicsItem
-{
-    Q_OBJECT
+class DesktopCircles;
 
-public:
-    explicit Tool(QGraphicsItem *parent = 0);
-    QRectF boundingRect() const;
-    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-};*/
-
 class DefaultDesktop : public Plasma::Containment
 {
     Q_OBJECT
@@ -62,6 +54,7 @@
 
 protected:
     void dropEvent(QGraphicsSceneDragDropEvent *event);
+    void resizeEvent(QGraphicsSceneResizeEvent *event);
 
 protected Q_SLOTS:
     void onAppletAdded(Plasma::Applet *, const QPointF &);
@@ -69,8 +62,14 @@
     void onAppletTransformedByUser();
     void onAppletTransformedItself();
     void refreshWorkingArea();
+    void nextDesktop();
+    void prevDesktop();
+    void repositionDesktopCircles();
 
 private:
+    Plasma::SvgWidget *m_prevDesktopButton;
+    Plasma::SvgWidget *m_nextDesktopButton;
+    DesktopCircles *m_desktopCircles;
     DesktopLayout *m_layout;
     bool dropping;
 };
Index: desktopcircles.cpp
===================================================================
--- desktopcircles.cpp	(revision 0)
+++ desktopcircles.cpp	(revision 0)
@@ -0,0 +1,101 @@
+/*
+ *   Copyright 2010 by Aaron Seigo <aseigo@kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License 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 "desktopcircles.h"
+
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+
+#include <KWindowSystem>
+
+#include <Plasma/Theme>
+
+static const int CIRCLE_SIZE = 24;
+static const int MARGIN = 8;
+
+DesktopCircles::DesktopCircles(QGraphicsWidget *parent)
+    : QGraphicsWidget(parent)
+{
+    connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, SLOT(currentDesktopChanged(int)));
+    connect(KWindowSystem::self(), SIGNAL(numberOfDesktopsChanged(int)), this, SLOT(numberOfDesktopsChanged(int)));
+
+    numberOfDesktopsChanged(KWindowSystem::numberOfDesktops());
+}
+
+void DesktopCircles::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget)
+{
+    Q_UNUSED(option)
+    Q_UNUSED(widget)
+
+    const int current = KWindowSystem::currentDesktop() - 1;
+    const int count = KWindowSystem::numberOfDesktops();
+    painter->setRenderHint(QPainter::Antialiasing);
+    QColor penColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
+    penColor.setAlpha(160);
+    QPen pen(penColor);
+    pen.setWidth(2);
+    painter->setPen(pen);
+    QColor fillColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
+    fillColor.setAlpha(80);
+    QBrush fill(fillColor);
+
+    for (int i = 0; i < count; ++i) {
+        const int margin = i * MARGIN;
+        const QRectF rect(CIRCLE_SIZE * i + margin, 0, CIRCLE_SIZE, CIRCLE_SIZE);
+
+        if (i == current) {
+            painter->setBrush(penColor);
+        } else {
+            painter->setBrush(fill);
+        }
+
+        painter->drawEllipse(rect);
+    }
+}
+
+void DesktopCircles::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    event->accept();
+}
+
+void DesktopCircles::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (!boundingRect().contains(event->pos())) {
+        return;
+    }
+
+    KWindowSystem::setCurrentDesktop(event->pos().x() / (CIRCLE_SIZE + MARGIN) + 1);
+}
+
+void DesktopCircles::numberOfDesktopsChanged(int count)
+{
+    const QSizeF newSize(count * CIRCLE_SIZE + (count - 1) * MARGIN, CIRCLE_SIZE);
+    setMinimumSize(newSize);
+    setMaximumSize(newSize);
+    setPreferredSize(newSize);
+    emit reposition();
+    update();
+}
+
+void DesktopCircles::currentDesktopChanged(int)
+{
+    update();
+}
+
+#include "desktopcircles.moc"
+
Index: desktopcircles.h
===================================================================
--- desktopcircles.h	(revision 0)
+++ desktopcircles.h	(revision 0)
@@ -0,0 +1,45 @@
+/*
+ *   Copyright 2010 by Aaron Seigo <aseigo@kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License 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 DESKTOPCIRCLES_H
+#define DESKTOPCIRCLES_H
+
+#include <QGraphicsWidget>
+
+class DesktopCircles : public QGraphicsWidget
+{
+    Q_OBJECT
+
+public:
+    DesktopCircles(QGraphicsWidget *parent = 0);
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget = 0);
+
+Q_SIGNALS:
+    void reposition();
+
+protected:
+    void mousePressEvent(QGraphicsSceneMouseEvent *);
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+
+private Q_SLOTS:
+    void numberOfDesktopsChanged(int count);
+    void currentDesktopChanged(int desktop);
+};
+
+#endif
+
Index: desktop.cpp
===================================================================
--- desktop.cpp	(revision 1150824)
+++ desktop.cpp	(working copy)
@@ -21,13 +21,21 @@
 #include "desktop.h"
 
 #include <KDebug>
+#include <KWindowSystem>
 
 #include <Plasma/Corona>
+#include <Plasma/Svg>
+#include <Plasma/SvgWidget>
 
+#include <desktopcircles.h>
+
 using namespace Plasma;
 
 DefaultDesktop::DefaultDesktop(QObject *parent, const QVariantList &args)
     : Containment(parent, args),
+      m_prevDesktopButton(new Plasma::SvgWidget(this)),
+      m_nextDesktopButton(new Plasma::SvgWidget(this)),
+      m_desktopCircles(new DesktopCircles(this)),
       dropping(false)
 {
     qRegisterMetaType<QImage>("QImage");
@@ -45,6 +53,19 @@
 
     setHasConfigurationInterface(true);
     //kDebug() << "!!! loading desktop";
+
+    Plasma::Svg *svg = new Plasma::Svg(this);
+    svg->setImagePath("widgets/arrows");
+
+    m_prevDesktopButton->setSvg(svg);
+    m_prevDesktopButton->setElementID("left-arrow");
+    connect(m_prevDesktopButton, SIGNAL(clicked(Qt::MouseButton)), this, SLOT(prevDesktop()));
+
+    m_nextDesktopButton->setSvg(svg);
+    m_nextDesktopButton->setElementID("right-arrow");
+    connect(m_nextDesktopButton, SIGNAL(clicked(Qt::MouseButton)), this, SLOT(nextDesktop()));
+
+    connect(m_desktopCircles, SIGNAL(reposition()), this, SLOT(repositionDesktopCircles()));
 }
 
 DefaultDesktop::~DefaultDesktop()
@@ -152,6 +173,42 @@
     dropping = false;
 }
 
+static const int bSize = 32;
+void DefaultDesktop::resizeEvent(QGraphicsSceneResizeEvent *)
+{
+    const int third = size().height() / 3 * 2;
+    m_prevDesktopButton->setGeometry(QRectF(12, third, bSize, bSize));
+    m_nextDesktopButton->setGeometry(QRectF(size().width() - 12 - bSize, third, bSize, bSize));
+    repositionDesktopCircles();
+}
+
+void DefaultDesktop::repositionDesktopCircles()
+{
+    const int third = size().height() / 3 * 2;
+    m_desktopCircles->setPos((size().width() - m_desktopCircles->size().width()) / 2,
+                             (third + (bSize / 2)) - (m_desktopCircles->size().height()) / 2);
+}
+
+void DefaultDesktop::nextDesktop()
+{
+    const int current = KWindowSystem::currentDesktop();
+    if (current + 1 > KWindowSystem::numberOfDesktops()) {
+        KWindowSystem::setCurrentDesktop(1);
+    } else {
+        KWindowSystem::setCurrentDesktop(current + 1);
+    }
+}
+
+void DefaultDesktop::prevDesktop()
+{
+    const int current = KWindowSystem::currentDesktop();
+    if (current < 2) {
+        KWindowSystem::setCurrentDesktop(KWindowSystem::numberOfDesktops());
+    } else {
+        KWindowSystem::setCurrentDesktop(current - 1);
+    }
+}
+
 K_EXPORT_PLASMA_APPLET(desktop, DefaultDesktop)
 
 #include "desktop.moc"
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 1150824)
+++ CMakeLists.txt	(working copy)
@@ -1,4 +1,5 @@
 set(desktop_SRCS
+    desktopcircles.cpp
     desktop.cpp
     itemspace.cpp
     desktoplayout.cpp)

