[meego-commits] 5658: Changes to Trunk/meegotouch-home

Anas Nashif nashif at linux.intel.com
Tue Jul 13 22:59:38 UTC 2010


Hi,
I have made the following changes to meegotouch-home in project Trunk. Please review and accept ASAP.

Thank You,
Anas Nashif

[This message was auto-generated]

---

Request #5658:

  submit:   Trunk:Testing/meegotouch-home(r4) -> Trunk/meegotouch-home


Message:
    Move to Trunk

State:   new          2010-07-13T10:54:21 nashif
Comment: None



changes files:
--------------
--- meegotouch-home.changes
+++ meegotouch-home.changes
@@ -0,0 +1,9 @@
+* Fri Jul 09 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> 0.21.14
+- Update to release tag 0.21.14-1
+- Remove obsolete patch: Modified-to-use-QIcon-to-load-application-icons-in-t
+- Temporarily disable tests as they fail to compile
+
+* Thu Jul 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.21.9
+- Change X-DUI to X-MEEGO-HS in the meegotouch-home.desktop autostart file
+- Resolve compile issue
+

old:
----
  0001-Modified-to-use-QIcon-to-load-application-icons-in-t.patch
  meegotouch-home-0.21.9.tar.bz2

new:
----
  comment_out_non-compiling_tests.patch
  fix_switcherbutton_compile.patch
  fix_unresolved_meegotouch_syms.patch
  meegotouch-home-0.21.14.tar.bz2

spec files:
-----------
--- meegotouch-home.spec
+++ meegotouch-home.spec
@@ -1,13 +1,13 @@
 # 
 # Do not Edit! Generated by:
-# spectacle version 0.17
+# spectacle version 0.18
 # 
 # >> macros
 # << macros
 
 Name:       meegotouch-home
 Summary:    MeeGo Touch Homescreen
-Version:    0.21.9
+Version:    0.21.14
 Release:    1
 Group:      System/Desktop
 License:    LGPL v2.1
@@ -15,9 +15,11 @@
 Source0:    %{name}-%{version}.tar.bz2
 Source1:    meegotouch-home.desktop
 Source100:  meegotouch-home.yaml
-Patch0:     0001-Modified-to-use-QIcon-to-load-application-icons-in-t.patch
-Patch1:     duihome-0.21.9-Default-to-Detailview.patch
-Patch2:     0001-Remove-labels-from-QuickLaunchBarButtons.patch
+Patch0:     duihome-0.21.9-Default-to-Detailview.patch
+Patch1:     0001-Remove-labels-from-QuickLaunchBarButtons.patch
+Patch2:     fix_unresolved_meegotouch_syms.patch
+Patch3:     comment_out_non-compiling_tests.patch
+Patch4:     fix_switcherbutton_compile.patch
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 BuildRequires:  pkgconfig(QtCore) >= 4.6.0
@@ -25,6 +27,7 @@
 BuildRequires:  pkgconfig(contextprovider-1.0)
 BuildRequires:  pkgconfig(xcomposite)
 BuildRequires:  pkgconfig(meegotouch)
+BuildRequires:  pkgconfig(contentaction-0.1)
 BuildRequires:  fdupes
 Provides:   duihome >= 0.21.9
 Obsoletes:   duihome < 0.21.9
@@ -47,12 +50,16 @@
 %prep
 %setup -q -n %{name}-%{version}
 
-# 0001-Modified-to-use-QIcon-to-load-application-icons-in-t.patch
-%patch0 -p1
 # duihome-0.21.9-Default-to-Detailview.patch
-%patch1 -p1
+%patch0 -p1
 # 0001-Remove-labels-from-QuickLaunchBarButtons.patch
+%patch1 -p1
+# fix_unresolved_meegotouch_syms.patch
 %patch2 -p1
+# comment_out_non-compiling_tests.patch
+%patch3 -p1
+# fix_switcherbutton_compile.patch
+%patch4 -p1
 # >> setup
 # << setup
 
@@ -117,7 +124,7 @@
 # >> files devel
 %defattr(-, root, root, -)
 %{_libdir}/libmeegotouchhome.so
-%{_libdir}/duihomescreen-tests
-%{_datadir}/duihomescreen-tests
+#%{_libdir}/duihomescreen-tests
+#%{_datadir}/duihomescreen-tests
 # << files devel
 

other changes:
--------------

++++++ comment_out_non-compiling_tests.patch (new)
--- comment_out_non-compiling_tests.patch
+++ comment_out_non-compiling_tests.patch
+From: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+Date: Fri, 09 JuL 2010
+Subject: [PATCH] Temporarily comment out tests
+
+These are failing to compile in a MeeGo environment. 
+
+Signed-off-by: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+
+diff -Naur meegotouch-home-0.21.14/projects.pro meegotouch-home-0.21.14-new/projects.pro
+--- meegotouch-home-0.21.14/projects.pro	2010-07-06 17:35:48.000000000 -0700
++++ meegotouch-home-0.21.14-new/projects.pro	2010-07-07 11:00:47.561682588 -0700
+@@ -8,8 +8,9 @@
+ TEMPLATE = subdirs
+ SUBDIRS = \
+     src \
+-    themes \
+-    tests
++    themes
++#    themes \
++#    tests
+ 
+ QMAKE_CLEAN += \
+     build-stamp \

++++++ fix_switcherbutton_compile.patch (new)
--- fix_switcherbutton_compile.patch
+++ fix_switcherbutton_compile.patch
+From: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+Date: Fri, 09 JuL 2010 
+Subject: [PATCH] XDamageSubtract() takes an int, not a pointer
+
+So replace NULL with 0 during initialization.
+
+Signed-off-by: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+
+diff -Naur meegotouch-home-0.21.14/src/home/switcherbuttonview.cpp meegotouch-home-0.21.14-new/src/home/switcherbuttonview.cpp
+--- meegotouch-home-0.21.14/src/home/switcherbuttonview.cpp	2010-07-06 17:35:48.000000000 -0700
++++ meegotouch-home-0.21.14-new/src/home/switcherbuttonview.cpp	2010-07-09 13:43:33.353678900 -0700
+@@ -331,7 +331,7 @@
+     Q_UNUSED(height);
+ #ifdef Q_WS_X11
+     if (xWindowPixmapDamage == damage) {
+-        X11Wrapper::XDamageSubtract(QX11Info::display(), xWindowPixmapDamage, NULL, NULL);
++        X11Wrapper::XDamageSubtract(QX11Info::display(), xWindowPixmapDamage, 0, 0);
+         update();
+     }
+ #else

++++++ fix_unresolved_meegotouch_syms.patch (new)
--- fix_unresolved_meegotouch_syms.patch
+++ fix_unresolved_meegotouch_syms.patch
+From: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+Date: Fri, 09 JuL 2010
+Subject: [PATCH] Add meegotouch to CONFIG to resolve undefined symbol error
+
+This error is seen during compilation.
+
+Signed-off-by: Kaitlin Rupert <kaitlin.rupert at linux.intel.com>
+
+diff -Naur meegotouch-home-0.21.14/tests/tests.pro meegotouch-home-0.21.14-new/tests/tests.pro
+--- meegotouch-home-0.21.14/tests/tests.pro	2010-07-06 17:35:48.000000000 -0700
++++ meegotouch-home-0.21.14-new/tests/tests.pro	2010-07-07 10:27:14.120838727 -0700
+@@ -27,6 +27,9 @@
+     ut_pagepositionindicatorview \
+     ut_test
+ 
++CONFIG += link_pkgconfig \
++    meegotouch
++
+ QMAKE_STRIP = echo
+ 
+ check.target = check

++++++ meegotouch-home-0.21.9.tar.bz2 -> meegotouch-home-0.21.14.tar.bz2
--- debian/api
+++ debian/api
+interface: LauncherButtonDesktopFileInterface
+type: file
+scope: Nokia Meego
+state: experimental
+libs-pkg: duihomescreen 
+dev-pkg: duihomescreen
+
+interface: com.meego.core.HomeScreen
+type: dbus
+scope: Platform
+state: experimental
+libs-pkg: duihomescreen
+dev-pkg: duihomescreen
+
+interface: com.meego.core.MDesktopBackgroundExtensionInterface
+type: dbus
+scope: Platform
+state: experimental
+libs-pkg: duihomescreen
+dev-pkg: duihomescreen
+
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,51 @@
+duihome (0.21.14-1) unstable; urgency=low
+
+  * Implemented: SWP#DUI-3399 Dim switcher background when there's content on the switcher
+  * Fixes: NB#176918 - Shading out of background wallpaper not dark enough.
+
+ -- Vesa Halttunen <vesa.halttunen at nokia.com>  Fri, 02 Jul 2010 15:19:34 +0300
+
+duihome (0.21.13-1) unstable; urgency=low
+
+  * Fixes: NB#174923 - Minimize/maximize animation end/begins at the edge of the screen
+  * Switcher detail view is usable again (if enabled)
+
+ -- Vesa Halttunen <vesa.halttunen at nokia.com>  Wed, 30 Jun 2010 19:31:16 +0300
+
+duihome (0.21.12-1) unstable; urgency=low
+
+  * Implemented: SWP#3148 Verify tappability of switcher thumbnail close button
+  * Implemented: SWP#DUI-3336 Application start-up indication
+  * Implemented: SWP#DUI-3244 Remove customized handling of call UI windows in switcher
+  * Fixes: NB#176177 - Launcher buttons are not placed in their expected positions
+
+ -- Vesa Halttunen <vesa.halttunen at nokia.com>  Mon, 28 Jun 2010 17:59:51 +0300
+
+duihome (0.21.11-2) unstable; urgency=low
+
+  * Removed a dependency to maemo-services package
+
+ -- Aki Koskinen <aki.koskinen at nokia.com>  Fri, 18 Jun 2010 13:25:00 +0300
+
+duihome (0.21.11-1) unstable; urgency=low
+
+  * Fixes: NB#167077 - [browser-blocker] Launcher is passing the substitution variables in the Exec field of the .desktop field as parameters when there is no substitution to be done
+  * Fixes: NB#171829 - Applications do not get _NET_ACTIVE_WINDOW event
+
+ -- Aki Koskinen <aki.koskinen at nokia.com>  Thu, 17 Jun 2010 16:11:00 +0300
+
+duihome (0.21.10-1) unstable; urgency=low
+
+  * Support for absolute icon paths in .desktop entry files
+  * Implemented: SWP#DUI-2666 Verify the UI flow when exiting and re-entering homescreen views
+  * Implemented: SWP#DUI-3013 Optimize switcher update when new windows are created, old ones are removed or windows update
+  * Fixes: NB#173173 - Launcher view switch needs too much panning. Panning paramteres have now been tuned as required by UI designers
+  * Fixes: NB#168403 - Shared QObjects being deleted directly in launcher code.
+  * Fixes: NB#173280 - Set wallpaper with large resolution image cause phone freeze
+  * Fixes: NB#169123 - Unlocalized application name in application grid
+
+ -- Aki Koskinen <aki.koskinen at nokia.com>  Mon, 14 Jun 2010 11:26:00 +0300
+
 duihome (0.21.9-1) unstable; urgency=low
 
   * Implemented: SWP#DUI-2724 Support to open launcher at a page where launcher item with certain application icon is displayed.
--- debian/control
+++ debian/control
@@ -6,7 +6,7 @@
   libmeegotouch-dev (>= 0.20.12),
   libqt4-dev (>= 4.6), libqt4-opengl-dev,
   libxcomposite-dev, libxext-dev,
-  libcontextsubscriber-dev, maemo-services-dev
+  libcontextsubscriber-dev, libcontentaction-dev (>= 0.1.9)
 Standards-Version: 3.7.2
 
 Package: duihomescreen
@@ -112,7 +112,8 @@
 Package: duihomescreen-tests
 Section: devel
 Architecture: any
-Depends: ci-testing, testrunner, duihomescreen (= ${binary:Version}), duihomescreen-plugins (= ${binary:Version})
+Depends: ci-testing, testrunner, duihomescreen (= ${binary:Version}), duihomescreen-plugins (= ${binary:Version}),
+  meego-env-dimming
 XB-Maemo-CI-Packages: duihomescreen
 XB-Maemo-CI-Stage: fast, staging
 Description: Testsuite for Direct UI Home screen
--- doc/mdoxy.cfg
+++ doc/mdoxy.cfg
@@ -43,8 +43,8 @@
 #---------------------------------------------------------------------------
 
 FILE_VERSION_FILTER   = "git-log --pretty=format:%H -n 1"
-INPUT                 = ./home/ \
-                        ./libduihome \
+INPUT                 = ./src/home/ \
+                        ./src/libduihome \
                         ./doc/src/
 FILE_PATTERNS         = *.cpp *.h *.dox
 RECURSIVE             = YES
--- doc/src/credits.dox
+++ doc/src/credits.dox
@@ -9,6 +9,12 @@
  Pauli Lehtinen 
  Tuomas Järvensivu
  Vesa Halttunen
+ Artem Egorkine
+ Mikko Levonmaa
+ Ville Voutilainen
+ Janne Sakko
+ Matti Vuorela
+ Jarkko Markkanen
 
 </pre>
 
--- doc/src/launcher.dox
+++ doc/src/launcher.dox
@@ -12,7 +12,7 @@
 
 The \e Type must be set to \e Application.
 
-The \e Icon must specify an icon id that is used to represent the application in the main menu.
+The \e Icon must specify the absolute path or ID of the icon that is used to represent the application in the main menu. If an icon ID is used the icon will first be located as described in the <a href="http://freedesktop.org/wiki/Standards/icon-theme-spec">Icon Theme Specification</a>. If an icon with the given ID is not found from those locations the icon is taken from the MeeGo Touch theme with the given ID. 
 
 The \e Name must be set to the unlocalized application name. You can however also provide localized application names. See \c MDesktopEntry documentation how to define localized names.
 
--- doc/src/news.dox
+++ doc/src/news.dox
@@ -1,5 +1,46 @@
 /*! \page news What's New in DirectUI Homescreen
 
+\section v02114 0.21.14
+
+\subsection New
+- The desktop background is blurred and dimmed if there is content on the desktop (in the switcher or in the launcher)
+
+\subsection bugs Bugs fixed
+- Shaded out background wallpaper was not dark enough
+
+\section v02113 0.21.13
+
+\subsection New
+- Switcher detail view is usable again (if enabled)
+
+\subsection bugs Bugs fixed
+- Minimize/maximize animation ended/began at the edge of the screen
+
+\section v02112 0.21.12
+
+\subsection New
+- It is much easier to close the tasks from the switcher
+- Launcher shows a progress indicator when an application is being started
+
+\subsection bugs Bugs fixed
+- Launcher buttons were not placed in their expected positions
+
+\section v02111 0.21.11
+
+\subsection bugs Bugs fixed
+- Launcher was passing the substitution variables in the Exec field of the .desktop field as parameters when there was no substitution to be done
+- Applications did not get _NET_ACTIVE_WINDOW event
+
+\section v02110 0.21.10
+
+\subsection New
+- Support for absolute icon paths in .desktop entry files.
+- Home screen provides the corrent UI flow.
+- New switcher buttons are added after a slight delay to speed up application startup.
+
+\subsection bugs Bugs fixed
+- Too large background images crashed the home screen
+
 \section v0219 0.21.9
 
 \subsection New
--- doc/src/switcher.dox
+++ doc/src/switcher.dox
@@ -13,10 +13,3 @@
 <strong>Overview</strong> mode shows more windows in a screen and smaller window icons. Amount of window icons per page can differ for portrait and landscape modes and also for different amounts of icons. In overview mode horizontal panning gestures switch between pages of window icons.
 
 <strong>Detail view</strong> mode shows more detailed window icons, but less icons on screen. In detail view mode panning gestures switch between focused window icon.
-
-\section priorization Window Priorization
-
-Currently call ui is the only prioritized window in application switcher. When call ui appears in window list, it will be moved as the first item on the switcher. Also in detail view mode switcher will be panned to focus call ui window icon and in overview mode switcher will be panned to the first page.
-
-Window is set as a call ui by setting the X Window property _NET_WM_WINDOW_TYPE of the window to value _NET_WM_WINDOW_TYPE_CALL.
-*/
--- mconfig.pri
+++ mconfig.pri
@@ -4,11 +4,6 @@
 unix {
      MEEGOHOME_DIR = $$M_INSTALL_DATA/duihome
      MEEGOHOME_THEMES_DIR = /usr/share/themes/base/meegotouch/duihome
-
-     TEST_SUITE_INSTALL_LOCATION=/usr/share/mfw-home-tests
-     TEST_APP_INSTALL_LOCATION=/usr/lib/mfw-home-tests
-     TEST_THEME_ROOT_LOCATION=/usr/share/themes/base/m
-     TEST_BENCHMARKS_INSTALL_LOCATION=/usr/share/mfw-home-benchmark-tests
 }
 mac {
      # Do mac stuff here
--- src/extensions/plaindesktopbackgroundextension/libduihome-plaindesktopbackgroundextension.css
+++ src/extensions/plaindesktopbackgroundextension/libduihome-plaindesktopbackgroundextension.css
@@ -1,7 +1,8 @@
 PlainDesktopBackgroundStyle {
     blur-radius: 10;
-    blur-duration: 1000;
-    blur-update-interval: 100;
+    brightness: 0.75;
+    defocus-duration: 500;
+    defocus-update-interval: 33;
 }
 PlainDesktopBackgroundStyle.Landscape {
     /* The name of the default background image */
--- src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundextension.cpp
+++ src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundextension.cpp
@@ -17,8 +17,8 @@
 **
 ****************************************************************************/
 
-#include <QPainter>
 #include <QApplication>
+#include <QPainter>
 #include <QGraphicsScene>
 #include <QGraphicsPixmapItem>
 #include <QGraphicsBlurEffect>
@@ -34,15 +34,13 @@
     desktop(NULL),
     landscapeGConfItem("/desktop/meego/background/landscape/picture_filename"),
     portraitGConfItem("/desktop/meego/background/portrait/picture_filename"),
-    blurFactor(0),
+    defocusFactor(0),
     blurRadius(0),
+    brightness(1),
     pixmapBeingUpdated(false)
 {
-    // Set up the blurring timeline
-    connect(&blurTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(setBlurFactor(qreal)));
-
-    // Connect to the windowListUpdated signal of the HomeApplication to get information about window list changes
-    connect(qApp, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), this, SLOT(setBlurTimeLineDirection(const QList<WindowInfo> &)));
+    // Set up the defocusing timeline
+    connect(&defocusTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(setDefocusFactor(qreal)));
 
     // Connect the GConf signals
     connect(&landscapeGConfItem, SIGNAL(valueChanged()), this, SLOT(updateLandscapePixmap()));
@@ -68,8 +66,9 @@
     // Get the defaults from the style
     const PlainDesktopBackgroundStyle *landscapeStyle = plainDesktopBackgroundStyle(M::Landscape);
     blurRadius = landscapeStyle->blurRadius();
-    blurTimeLine.setDuration(landscapeStyle->blurDuration());
-    blurTimeLine.setUpdateInterval(landscapeStyle->blurUpdateInterval());
+    brightness = landscapeStyle->brightness();
+    defocusTimeLine.setDuration(landscapeStyle->defocusDuration());
+    defocusTimeLine.setUpdateInterval(landscapeStyle->defocusUpdateInterval());
     landscapeDefaultBackgroundImage = landscapeStyle->defaultBackgroundImage();
     MTheme::releaseStyle(landscapeStyle);
 
@@ -101,42 +100,40 @@
     PlainDesktopBackgroundPixmap *pixmap = (angle == M::Angle0 || angle == M::Angle180) ? landscapePixmap.data() : portraitPixmap.data();
 
     if (pixmap != NULL) {
-        if (pixmap->pixmap() != NULL && blurFactor < 1) {
-            // The normal background pixmap needs to be drawn unless the background should be completely blurred
+        if (pixmap->pixmap() != NULL && defocusFactor < 1) {
+            // The normal background pixmap needs to be drawn unless the background should be completely defocused
             drawPixmap(painter, *pixmap->pixmap(), boundingRect);
         }
 
-        if (pixmap->blurredPixmap() != NULL && blurFactor > 0) {
-            // The blurred background pixmap needs to be drawn if the background should be blurred at all
-            painter->setOpacity(blurFactor);
-            drawPixmap(painter, *pixmap->blurredPixmap(), boundingRect);
+        if (pixmap->defocusedPixmap() != NULL && defocusFactor > 0) {
+            // The defocused background pixmap needs to be drawn if the background should be defocused at all
+            painter->setOpacity(defocusFactor);
+            drawPixmap(painter, *pixmap->defocusedPixmap(), boundingRect);
         }
     }
 }
 
-void PlainDesktopBackgroundExtension::setBlurTimeLineDirection(const QList<WindowInfo> &windowList)
+void PlainDesktopBackgroundExtension::setDefocused(bool defocused)
 {
-    // If there are windows in the window list the background should be blurred (blurFactor should be animated from 0 to 1).
-    // If there are no windows in the window list the background should not be blurred (blurFactor should be animated from 1 to 0).
-    QTimeLine::Direction direction = windowList.length() > 0 ? QTimeLine::Forward : QTimeLine::Backward;
-    if (blurTimeLine.direction() != direction) {
-        blurTimeLine.toggleDirection();
+    QTimeLine::Direction direction = defocused ? QTimeLine::Forward : QTimeLine::Backward;
+    if (defocusTimeLine.direction() != direction) {
+        defocusTimeLine.toggleDirection();
     }
 
-    if (blurTimeLine.state() == QTimeLine::NotRunning) {
-        blurTimeLine.resume();
+    if (defocusTimeLine.state() == QTimeLine::NotRunning) {
+        defocusTimeLine.resume();
     }
 }
 
-void PlainDesktopBackgroundExtension::setBlurFactor(qreal blurFactor)
+void PlainDesktopBackgroundExtension::setDefocusFactor(qreal defocusFactor)
 {
-    if (this->blurFactor != blurFactor) {
-        this->blurFactor = blurFactor;
+    if (this->defocusFactor != defocusFactor) {
+        this->defocusFactor = defocusFactor;
         if (desktop != NULL) {
             desktop->update();
         }
-        // Set a property with the blur factor to make functional testing possible
-        qApp->setProperty("plainDesktopBackgroundExtensionBlurFactor", QVariant(blurFactor));
+        // Set a property with the defocus factor to make functional testing possible
+        qApp->setProperty("plainDesktopBackgroundExtensionDefocusFactor", QVariant(defocusFactor));
     }
 }
 
@@ -167,17 +164,17 @@
         bool previousPixmapExists = !(*pixmap).isNull();
         QString oldName = previousPixmapExists ? (*pixmap)->pixmapName() : "";
         QString newName = gConfItem.value().toString();
-        *pixmap = QSharedPointer<PlainDesktopBackgroundPixmap>(new PlainDesktopBackgroundPixmap(newName, defaultName, blurRadius));
+        *pixmap = QSharedPointer<PlainDesktopBackgroundPixmap>(new PlainDesktopBackgroundPixmap(newName, defaultName, blurRadius, brightness));
         QString actualName = (*pixmap)->pixmapName();
 
         if (previousPixmapExists && !(newName.isEmpty() && actualName == defaultName) && (actualName != newName && !oldName.isEmpty())) {
             // The loaded pixmap is not the requested one so something went wrong. Use the old pixmap name instead.
             pixmapBeingUpdated = true;
             gConfItem.set(oldName);
-            *pixmap = QSharedPointer<PlainDesktopBackgroundPixmap>(new PlainDesktopBackgroundPixmap(oldName, defaultName, blurRadius));
+            *pixmap = QSharedPointer<PlainDesktopBackgroundPixmap>(new PlainDesktopBackgroundPixmap(oldName, defaultName, blurRadius, brightness));
             pixmapBeingUpdated = false;
 
-            // Redraw the desktop if the blurred pixmap becomes available later
+            // Redraw the desktop if the defocused pixmap becomes available later
             connect((*pixmap).data(), SIGNAL(pixmapUpdated()), this, SLOT(updateDesktop()));
         }
 
--- src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundextension.h
+++ src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundextension.h
@@ -50,6 +50,7 @@
 
     //! \reimp
     virtual void setDesktopInterface(MDesktopInterface &desktopInterface);
+    virtual void setDefocused(bool defocused);
     virtual void drawBackground(QPainter *painter, const QRectF &boundingRect) const;
     virtual bool initialize(const QString &interface);
     virtual QGraphicsWidget *widget();
@@ -57,16 +58,11 @@
 
 private slots:
     /*!
-     * \brief Sets the blur time line direction based on whether there are windows in the window list.
-     */
-    void setBlurTimeLineDirection(const QList<WindowInfo> &windowList);
-
-    /*!
-     * Sets the blur factor.
+     * Sets the defocus factor.
      *
-     * \param blurFactor the new blur factor
+     * \param defocusFactor the new defocus factor
      */
-    void setBlurFactor(qreal blurFactor);
+    void setDefocusFactor(qreal defocusFactor);
 
     /*!
      * Updates the landscape pixmap.
@@ -114,15 +110,18 @@
     //! The name of the portrait default background image
     QString portraitDefaultBackgroundImage;
 
-    //! Blurring factor
-    qreal blurFactor;
+    //! Defocusing factor
+    qreal defocusFactor;
 
-    //! Blurring timeline
-    QTimeLine blurTimeLine;
+    //! Defocusing timeline
+    QTimeLine defocusTimeLine;
 
     //! Blur radius (in pixels)
     int blurRadius;
 
+    //! Brightness (from 0 to 1)
+    qreal brightness;
+
     //! Whether a pixmap is being updated or not
     bool pixmapBeingUpdated;
 };
--- src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundpixmap.cpp
+++ src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundpixmap.cpp
@@ -18,20 +18,36 @@
 ****************************************************************************/
 
 #include <QPainter>
+#include <QImageReader>
 #include <QGraphicsScene>
 #include <QGraphicsPixmapItem>
 #include <QGraphicsBlurEffect>
 #include <MTheme>
 #include "plaindesktopbackgroundpixmap.h"
 
-PlainDesktopBackgroundPixmap::PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius) :
+static const int PIXMAP_WIDTH_MAX = 2048;
+static const int PIXMAP_HEIGHT_MAX = 2048;
+
+PlainDesktopBackgroundPixmap::PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius, qreal brightness) :
         blurRadius_(blurRadius),
+        brightness_(brightness),
         pixmapFromTheme_(NULL)
 {
     if (name.startsWith('/')) {
         // Absolute path: Load from a file
-        pixmapFromFile_ = QSharedPointer<QPixmap>(new QPixmap);
-        if (pixmapFromFile_->load(name)) {
+        bool success = false;
+
+        QImageReader imageReader(name);
+        if (imageReader.canRead()) {
+            QSize size = imageReader.size();
+            if (size.height() <= PIXMAP_HEIGHT_MAX && size.width() <= PIXMAP_WIDTH_MAX) {
+                // Only load the pixmap if it's not too big
+                pixmapFromFile_ = QSharedPointer<QPixmap>(new QPixmap);
+                success = pixmapFromFile_->load(name);
+            }
+        }
+
+        if (success) {
             // Loading succeeded
             pixmapName_ = name;
         } else {
@@ -52,8 +68,8 @@
         pixmapName_ = defaultName;
     }
 
-    // Create a blurred version
-    createBlurredPixmap();
+    // Create a defocused version
+    createDefocusedPixmap();
 }
 
 PlainDesktopBackgroundPixmap::~PlainDesktopBackgroundPixmap()
@@ -63,22 +79,22 @@
     }
 }
 
-void PlainDesktopBackgroundPixmap::createBlurredPixmap()
+void PlainDesktopBackgroundPixmap::createDefocusedPixmap()
 {
     // Disconnect previous pixmapRequestsFinished() connections if any
-    disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), this, SLOT(createBlurredPixmap()));
+    disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), this, SLOT(createDefocusedPixmap()));
 
     if (pixmapFromFile_.isNull() && pixmapFromTheme_ != NULL && pixmapFromTheme_->isNull()) {
         // A pixmap from the theme is being used but it is not available yet: listen to pixmapRequestsFinished() signals
-        connect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), this, SLOT(createBlurredPixmap()));
+        connect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), this, SLOT(createDefocusedPixmap()));
     } else {
         // A pixmap from a file is being used or a pixmap from the theme is being used and it is available
-        blurredPixmap_ = QSharedPointer<QPixmap>(createBlurredPixmap(*pixmap(), blurRadius_));
+        defocusedPixmap_ = QSharedPointer<QPixmap>(createDefocusedPixmap(*pixmap(), blurRadius_, brightness_));
         emit pixmapUpdated();
     }
 }
 
-QPixmap *PlainDesktopBackgroundPixmap::createBlurredPixmap(const QPixmap &pixmap, int blurRadius)
+QPixmap *PlainDesktopBackgroundPixmap::createDefocusedPixmap(const QPixmap &pixmap, int blurRadius, qreal brightness)
 {
     // Create a scene and put the pixmap on it using a blur effect
     QGraphicsScene scene;
@@ -86,17 +102,18 @@
     QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
     blur->setBlurRadius(blurRadius);
     item->setGraphicsEffect(blur);
+    item->setOpacity(brightness);
     scene.addItem(item);
 
-    // Create a pixmap for the blurred version of the pixmap
-    QPixmap *blurredPixmap = new QPixmap(pixmap.width(), pixmap.height());
-    blurredPixmap->fill(Qt::black);
+    // Create a pixmap for the defocused version of the pixmap
+    QPixmap *defocusedPixmap = new QPixmap(pixmap.width(), pixmap.height());
+    defocusedPixmap->fill(Qt::black);
 
     // Paint the scene to the pixmap
-    QPainter painter(blurredPixmap);
+    QPainter painter(defocusedPixmap);
     scene.render(&painter);
 
-    return blurredPixmap;
+    return defocusedPixmap;
 }
 
 const QPixmap *PlainDesktopBackgroundPixmap::pixmap() const
@@ -104,9 +121,9 @@
     return pixmapFromFile_.isNull() ? pixmapFromTheme_ : pixmapFromFile_.data();
 }
 
-const QPixmap *PlainDesktopBackgroundPixmap::blurredPixmap() const
+const QPixmap *PlainDesktopBackgroundPixmap::defocusedPixmap() const
 {
-    return blurredPixmap_.data();
+    return defocusedPixmap_.data();
 }
 
 QString PlainDesktopBackgroundPixmap::pixmapName() const
--- src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundpixmap.h
+++ src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundpixmap.h
@@ -41,8 +41,9 @@
      * \param name the name of the pixmap to load
      * \param defaultName the name of the default pixmap to load if loading the user selected one fails
      * \param blurRadius the blur radius (in pixels)
+     * \param brightness the brightness (from 0 to 1)
      */
-    PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius);
+    PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius, qreal brightness);
 
     /*!
      * Frees the background pixmap.
@@ -57,11 +58,11 @@
     const QPixmap *pixmap() const;
 
     /*!
-     * Returns the blurred pixmap.
+     * Returns the defocused pixmap.
      *
-     * \return the blurred pixmap
+     * \return the defocused pixmap
      */
-    const QPixmap *blurredPixmap() const;
+    const QPixmap *defocusedPixmap() const;
 
     /*!
      * Returns the name of the pixmap.
@@ -72,17 +73,17 @@
 
 private slots:
     /*!
-     * Creates a blurred pixmap from the pixmap if the pixmap is loaded from
+     * Creates a defocused pixmap from the pixmap if the pixmap is loaded from
      * a file or if it is loaded from the theme and it is already available.
      * If the pixmap is loaded from the theme and is not yet available starts
      * listening to pixmapRequestsFinished() signals to blur the pixmap when
      * it is available.
      */
-    void createBlurredPixmap();
+    void createDefocusedPixmap();
 
 signals:
     /*!
-     * Signaled when the pixmap is updated (blurred pixmap becomes available).
+     * Signaled when the pixmap is updated (defocused pixmap becomes available).
      */
     void pixmapUpdated();
 
@@ -90,26 +91,30 @@
     // The blur radius for the pixmap
     int blurRadius_;
 
+    // The brightness for the pixmap
+    qreal brightness_;
+
     // The pixmap if read from the theme
     const QPixmap *pixmapFromTheme_;
 
     //! The pixmap if read from a file
     QSharedPointer<QPixmap> pixmapFromFile_;
 
-    //! A blurred version of the pixmap
-    QSharedPointer<QPixmap> blurredPixmap_;
+    //! A defocused version of the pixmap
+    QSharedPointer<QPixmap> defocusedPixmap_;
 
     //! The name of the pixmap
     QString pixmapName_;
 
     /*!
-     * Creates a blurred pixmap from a pixmap.
+     * Creates a defocused pixmap from a pixmap.
      *
      * \param pixmap the pixmap to blur
      * \param blurRadius the blur radius (in pixels)
-     * \return a blurred version of the pixmap
+     * \param brightness the brightness (from 0 to 1)
+     * \return a defocused version of the pixmap
      */
-    static QPixmap *createBlurredPixmap(const QPixmap &pixmap, int blurRadius);
+    static QPixmap *createDefocusedPixmap(const QPixmap &pixmap, int blurRadius, qreal brightness);
 
 #ifdef UNIT_TEST
     friend class Ut_PlainDesktopBackgroundPixmap;
--- src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundstyle.h
+++ src/extensions/plaindesktopbackgroundextension/plaindesktopbackgroundstyle.h
@@ -30,11 +30,14 @@
     //! The blur radius (in pixels)
     M_STYLE_ATTRIBUTE(int, blurRadius, BlurRadius)
 
-    //! The blur duration (in ms)
-    M_STYLE_ATTRIBUTE(int, blurDuration, BlurDuration)
+    //! The brightness for dimming (from 0 to 1)
+    M_STYLE_ATTRIBUTE(qreal, brightness, Brightness)
 
-    //! The blur update interval (in ms)
-    M_STYLE_ATTRIBUTE(int, blurUpdateInterval, BlurUpdateInterval)
+    //! The defocus duration (in ms)
+    M_STYLE_ATTRIBUTE(int, defocusDuration, DefocusDuration)
+
+    //! The defocus update interval (in ms)
+    M_STYLE_ATTRIBUTE(int, defocusUpdateInterval, DefocusUpdateInterval)
 
     //! The name of the default background image
     M_STYLE_ATTRIBUTE(QString, defaultBackgroundImage, DefaultBackgroundImage)
--- src/home/appletspace.cpp
+++ src/home/appletspace.cpp
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#include "appletspace.h"
-#include "appletspacemodel.h"
-#include <QDebug>
-
-AppletSpace::AppletSpace(MWidget *parent) :
-    MWidgetController(new AppletSpaceModel, parent)
-{
-}
-
-AppletSpace::~AppletSpace()
-{
-}
-
-void AppletSpace::setEnabled(bool enabled)
-{
-    MWidgetController::setEnabled(enabled);
-
-    // Show or hide the button
-    model()->setCloseButtonVisible(enabled);
-}
--- src/home/appletspace.h
+++ src/home/appletspace.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef APPLETSPACE_H_
-#define APPLETSPACE_H_
-
-#include <MWidgetController>
-#include "appletspacemodel.h"
-
-/*!
- * A widget that contains an applet space (mashup canvas).
- */
-class AppletSpace : public MWidgetController
-{
-    Q_OBJECT
-    M_CONTROLLER(AppletSpace)
-
-public:
-    /*!
-     * Constructs a AppletSpace widget.
-     *
-     * \param parent Parent for the widget, defaults to NULL
-     */
-    AppletSpace(MWidget *parent = NULL);
-
-    /*!
-     * Destroys the AppletSpace.
-     */
-    virtual ~AppletSpace();
-
-    /*!
-     * If enabled is true, the applet space is enabled (items can be clicked, button is visible); otherwise, it is disabled.
-     *
-     * The applet space is disabled by default.
-     *
-     * \param enabled if true, the applet space is enabled; otherwise, it is disabled
-     */
-    void setEnabled(bool enabled);
-
-signals:
-    //! Sent when the applet space should be closed
-    void closed();
-};
-
-#endif /* APPLETSPACE_H_ */
--- src/home/appletspacemodel.h
+++ src/home/appletspacemodel.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef APPLETSPACEMODEL_H_
-#define APPLETSPACEMODEL_H_
-
-#include <mwidgetmodel.h>
-
-class AppletSpaceModel : public MWidgetModel
-{
-    Q_OBJECT
-    M_MODEL(AppletSpaceModel)
-
-private:
-    //! Whether the close button should be visible or not
-    M_MODEL_PROPERTY(bool, closeButtonVisible, CloseButtonVisible, true, false)
-};
-
-#endif /* APPLETSPACEMODEL_H_ */
--- src/home/appletspacestyle.h
+++ src/home/appletspacestyle.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-#ifndef APPLETSPACESTYLE_H
-#define APPLETSPACESTYLE_H
-
-#include <mextendingbackgroundstyle.h>
-
-class AppletSpaceStyle : public MExtendingBackgroundStyle
-{
-    Q_OBJECT
-    M_STYLE(AppletSpaceStyle)
-};
-
-class AppletSpaceStyleContainer : public MExtendingBackgroundStyleContainer
-{
-    M_STYLE_CONTAINER(AppletSpaceStyle)
-};
-
-#endif
--- src/home/appletspaceview.cpp
+++ src/home/appletspaceview.cpp
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#include <QGraphicsLinearLayout>
-#include <MModalSceneWindow>
-#include <MPannableViewport>
-#include <MMashupCanvas>
-#include <MOverlay>
-#include <MButton>
-#include "appletspaceview.h"
-#include "appletspace.h"
-#include <QDebug>
-
-AppletSpaceView::AppletSpaceView(AppletSpace *controller) :
-    MExtendingBackgroundView(controller),
-    controller(controller),
-    closeButtonOverlay(new MOverlay),
-    closeButton(new MButton(closeButtonOverlay))
-{
-    // Put the mashup canvas into the bottom of the layout
-    QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
-    layout->setContentsMargins(0, 0, 0, 0);
-    controller->setLayout(layout);
-
-    mashupCanvas = new MMashupCanvas("appletcanvas");
-    layout->addStretch();
-    layout->addItem(mashupCanvas);
-
-    // Set close button properties
-    closeButton->setViewType("icon");
-    closeButton->setObjectName("AppletSpaceCloseButton");
-    closeButton->setIconID("icon-m-framework-close");
-    QObject::connect(closeButton, SIGNAL(clicked()), controller, SIGNAL(closed()));
-
-    closeButtonOverlay->setObjectName("AppletSpaceCloseButtonOverlay");
-}
-
-AppletSpaceView::~AppletSpaceView()
-{
-    delete closeButtonOverlay;
-}
-
-void AppletSpaceView::updateData(const QList<const char *>& modifications)
-{
-    MExtendingBackgroundView::updateData(modifications);
-    const char *member;
-    foreach(member, modifications) {
-        if (member == AppletSpaceModel::CloseButtonVisible) {
-            // Set the visibility of the button
-            if (model()->closeButtonVisible()) {
-                closeButtonOverlay->appear();
-            } else {
-                closeButtonOverlay->disappear();
-            }
-        }
-    }
-}
-
-M_REGISTER_VIEW_NEW(AppletSpaceView, AppletSpace)
--- src/home/appletspaceview.h
+++ src/home/appletspaceview.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef APPLETSPACEVIEW_H_
-#define APPLETSPACEVIEW_H_
-
-#include <mextendingbackgroundview.h>
-#include "appletspacestyle.h"
-#include "appletspacemodel.h"
-
-class AppletSpace;
-class MMashupCanvas;
-class MOverlay;
-class MButton;
-
-/*!
- * The applet space view contains a mashup
- */
-class AppletSpaceView : public MExtendingBackgroundView
-{
-    Q_OBJECT
-    M_VIEW(AppletSpaceModel, AppletSpaceStyle)
-
-public:
-    /*!
-     * Constructs an AppletSpaceView.
-     *
-     * \param container the AppletSpace controller to be used
-     */
-    AppletSpaceView(AppletSpace *container);
-
-    /*!
-     * Destroys the AppletSpaceView.
-     */
-    virtual ~AppletSpaceView();
-
-private slots:
-    //! \reimp
-    virtual void updateData(const QList<const char *>& modifications);
-    //! \reimp_end
-
-private:
-    //! The AppletSpace controller
-    AppletSpace *controller;
-    //! The mashup canvas
-    MMashupCanvas *mashupCanvas;
-    //! An overlay for the close button
-    MOverlay *closeButtonOverlay;
-    //! A close button
-    MButton *closeButton;
-};
-
-#endif /* APPLETSPACEVIEW_H_ */
--- src/home/desktop.h
+++ src/home/desktop.h
@@ -44,12 +44,6 @@
      * Destroys the Desktop.
      */
     virtual ~Desktop();
-
-signals:
-    /*!
-     * \brief Signaled when the viewport size, the panning range or the panning position changes.
-     */
-    void viewportSizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos);
 };
 
 #endif // DESKTOP_H
--- src/home/desktopview.cpp
+++ src/home/desktopview.cpp
@@ -16,7 +16,6 @@
 ** of this file.
 **
 ****************************************************************************/
-
 #ifdef BENCHMARKS_ON
 #include <QTextStream>
 #include <QFile>
@@ -33,7 +32,6 @@
 #include "desktop.h"
 #include "mainwindow.h"
 #include "switcher.h"
-#include "appletspace.h"
 #include "quicklaunchbar.h"
 #include "mdesktopbackgroundextensioninterface.h"
 #include "mfiledatastore.h"
@@ -41,7 +39,7 @@
 #include <MViewCreator>
 #include <MDeviceProfile>
 #include <MSceneManager>
-#include <MModalSceneWindow>
+#include <MSceneWindow>
 #include <MPannableViewport>
 #include <MApplication>
 #include <MOverlay>
@@ -106,61 +104,45 @@
 DesktopView::DesktopView(Desktop *desktop) :
     MWidgetView(desktop),
     switcher(new Switcher),
+    switcherWindow(new MSceneWindow),
+    switcherHasContent(false),
     launcherDataStore(NULL),
     launcher(NULL),
-    launcherWindow(new MModalSceneWindow),
+    launcherWindow(new MSceneWindow),
+    launcherVisible(false),
     quickLaunchBar(NULL),
     quickLaunchBarWindow(new MOverlay),
-    appletSpace(new AppletSpace),
-    appletSpaceWindow(new MModalSceneWindow),
-    appletSpaceViewport(new MPannableViewport(appletSpaceWindow)),
     backgroundExtensionArea(new MApplicationExtensionArea("com.meego.core.MDesktopBackgroundExtensionInterface/1.0"))
 {
+    // Add the switcher into a scene window
+    switcher->setObjectName("OverviewSwitcher");
+    QGraphicsLinearLayout *windowLayout = new QGraphicsLinearLayout();
+    windowLayout->setContentsMargins(0, 0, 0, 0);
+    switcherWindow->setLayout(windowLayout);
+    switcherWindow->setObjectName("SwitcherWindow");
+    windowLayout->addItem(switcher);
+    MainWindow::instance()->sceneManager()->appearSceneWindowNow(switcherWindow);
+
     // Create the launcher data store
     launcherDataStore = createLauncherDataStore();
 
-    // Create the main layout that contains the switcher etc.
-    QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(Qt::Vertical);
-    mainLayout->setContentsMargins(0, 0, 0, 0);
-    mainLayout->setSpacing(0);
-    desktop->setLayout(mainLayout);
-
-    // Add a placeholder for the status area TODO remove hardcoded values
-    QGraphicsWidget *widget = new QGraphicsWidget;
-    widget->setMinimumHeight(28);
-    widget->setMaximumHeight(28);
-    mainLayout->addItem(widget);
-
-    // Create switcher
-    switcher->setObjectName("OverviewSwitcher");
-    mainLayout->addItem(switcher);
-    connect(desktop, SIGNAL(viewportSizePosChanged(const QSizeF &, const QRectF &, const QPointF &)),
-            switcher, SLOT(viewportSizePosChanged(const QSizeF &, const QRectF &, const QPointF &)));
-
-    // Add a placeholder for the quick launch bar TODO remove hardcoded values
-    widget = new QGraphicsWidget;
-    widget->setMinimumHeight(76);
-    widget->setMaximumHeight(76);
-    mainLayout->addItem(widget);
-
     // Create a quick launch bar and put it in a scene window
     quickLaunchBar = new QuickLaunchBar(launcherDataStore);
     connect(quickLaunchBar, SIGNAL(toggleLauncherButtonClicked()), this, SLOT(toggleLauncher()));
-    connect(quickLaunchBar, SIGNAL(toggleAppletSpaceButtonClicked()), this, SLOT(toggleAppletSpace()));
-    QGraphicsLinearLayout *windowLayout = new QGraphicsLinearLayout();
+    windowLayout = new QGraphicsLinearLayout();
     windowLayout->setContentsMargins(0, 0, 0, 0);
     windowLayout->addItem(quickLaunchBar);
     quickLaunchBarWindow->setLayout(windowLayout);
     quickLaunchBarWindow->setObjectName("QuickLaunchBarOverlay");
     MainWindow::instance()->sceneManager()->appearSceneWindowNow(quickLaunchBarWindow);
 
-    windowLayout = new QGraphicsLinearLayout();
-    windowLayout->setContentsMargins(0, 0, 0, 0);
-
-    // The launcher is added into a modal scene window
+    // Add the launcher into a scene window
     launcher = new Launcher(launcherDataStore);
-    connect(launcher, SIGNAL(launcherButtonClicked()), this, SLOT(toggleLauncher()));
     connect(qApp, SIGNAL(focusToLauncherAppRequested(const QString &)), this, SLOT(showLauncherAndPanToPage(const QString &)));
+    connect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), this, SLOT(updateLauncherVisiblity(const QList<WindowInfo> &)));
+    connect(qApp, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), this, SLOT(setSwitcherHasContent(const QList<WindowInfo> &)));
+    windowLayout = new QGraphicsLinearLayout();
+    windowLayout->setContentsMargins(0, 0, 0, 0);
     launcherWindow->setLayout(windowLayout);
     launcherWindow->setObjectName("LauncherWindow");
     windowLayout->addItem(launcher);
@@ -169,20 +151,6 @@
     MainWindow::instance()->sceneManager()->appearSceneWindowNow(launcherWindow);
     MainWindow::instance()->sceneManager()->disappearSceneWindowNow(launcherWindow);
 
-    // Put the applet space inside a pannable viewport
-    connect(appletSpace, SIGNAL(closed()), this, SLOT(toggleAppletSpace()));
-    appletSpaceViewport->setWidget(appletSpace);
-    appletSpaceViewport->setMinimumSize(MApplication::activeWindow()->visibleSceneSize());
-    appletSpaceViewport->setMaximumSize(MApplication::activeWindow()->visibleSceneSize());
-
-    // Create a layout for the applet space scene window
-    windowLayout = new QGraphicsLinearLayout();
-    windowLayout->setContentsMargins(0, 0, 0, 0);
-    windowLayout->addItem(appletSpaceViewport);
-    appletSpaceWindow->setLayout(windowLayout);
-    appletSpaceWindow->setObjectName("AppletSpaceWindow");
-    MainWindow::instance()->sceneManager()->disappearSceneWindowNow(appletSpaceWindow);
-
 #ifdef BENCHMARKS_ON
     connect(MApplication::instance(), SIGNAL(startBenchmarking()), this, SLOT(startBenchmarking()));
     connect(MApplication::instance(), SIGNAL(stopBenchmarking()), this, SLOT(stopBenchmarking()));
@@ -193,14 +161,18 @@
             this, SLOT(addExtension(MApplicationExtensionInterface*)));
     connect(backgroundExtensionArea, SIGNAL(extensionRemoved(MApplicationExtensionInterface*)),
             this, SLOT(removeExtension(MApplicationExtensionInterface*)));
+    backgroundExtensionArea->setInProcessFilter(QRegExp("/duihome-plaindesktopbackgroundextension.desktop$"));
+    backgroundExtensionArea->setOutOfProcessFilter(QRegExp("$^"));
     backgroundExtensionArea->init();
+
+    setSceneWindowOrder();
 }
 
 DesktopView::~DesktopView()
 {
+    delete switcherWindow;
     delete launcherWindow;
     delete quickLaunchBarWindow;
-    delete appletSpaceWindow;
     delete backgroundExtensionArea;
     delete launcherDataStore;
 }
@@ -234,68 +206,77 @@
     }
 }
 
-void DesktopView::toggleLauncher()
+void DesktopView::showLauncherAndPanToPage(const QString &desktopFileEntry)
 {
-    if (launcherWindow->isVisible()) {
-        hideLauncher();
-    } else {
+    if(launcher->panToPage(desktopFileEntry) >= 0 || desktopFileEntry.isEmpty()) {
         showLauncher();
+        MainWindow::instance()->activateWindow();
+        MainWindow::instance()->raise();
     }
 }
 
-void DesktopView::showLauncherAndPanToPage(const QString &desktopFileEntry)
+void DesktopView::updateLauncherVisiblity(const QList<WindowInfo> &windowList)
 {
-    if(launcher->panToPage(desktopFileEntry) >= 0 || desktopFileEntry.isEmpty()) {
+    if (launcherWindow->isVisible() && !windowList.isEmpty()) {
+        const QList<Atom>& windowTypes = windowList.last().types();
+        if (!windowTypes.contains(WindowInfo::NotificationAtom) &&
+            !windowTypes.contains(WindowInfo::DesktopAtom) &&
+            !windowTypes.contains(WindowInfo::DialogAtom) &&
+            !windowTypes.contains(WindowInfo::MenuAtom)) {
+            hideLauncher();
+        }
+    }
+}
+
+void DesktopView::toggleLauncher()
+{
+    if (launcherWindow->isVisible()) {
+        hideLauncher();
+    } else {
+        launcher->setFirstPage();
         showLauncher();
-        MainWindow::instance()->activateWindow();
-        MainWindow::instance()->raise();
     }
 }
 
 void DesktopView::showLauncher()
 {
     MainWindow::instance()->sceneManager()->appearSceneWindow(launcherWindow);
+    MainWindow::instance()->sceneManager()->disappearSceneWindow(switcherWindow);
+    setSceneWindowOrder();
 
-    // Set the launcher window below other modal scene windows
-    // @todo TODO get rid of the hardcoded value when MSceneManager enables dynamic allocation of Z values
-    launcherWindow->parentItem()->setZValue(300);
-
-    launcher->setEnabled(true);
-
-    // TODO : does this have to be animated??
-    switcher->setVisible(false);
+    launcherVisible = true;
+    setDefocused();
 }
 
 void DesktopView::hideLauncher()
 {
-    // Disable the launcher so that during the disappear animation of
-    // the dialog it's not possible to launch another application
-    launcher->setEnabled(false);
-
-    // Scroll the launcher above the screen
     MainWindow::instance()->sceneManager()->disappearSceneWindow(launcherWindow);
+    MainWindow::instance()->sceneManager()->appearSceneWindow(switcherWindow);
+    setSceneWindowOrder();
 
-    // TODO : does this have to be animated??
-    switcher->setVisible(true);
+    launcherVisible = false;
+    setDefocused();
 }
 
-void DesktopView::toggleAppletSpace()
+void DesktopView::setSceneWindowOrder()
 {
-    if (appletSpaceWindow->isVisible()) {
-        appletSpaceWindow->disappear();
-        appletSpace->setEnabled(false);
-    } else {
-        appletSpaceWindow->appear();
-        appletSpace->setEnabled(true);
-    }
+    // Keep the switcher and launcher windows behind the quick launch bar window
+    launcherWindow->setZValue(quickLaunchBarWindow->zValue() - 1);
+    switcherWindow->setZValue(quickLaunchBarWindow->zValue() - 2);
+}
+
+void DesktopView::setSwitcherHasContent(const QList<WindowInfo> &windowList)
+{
+    switcherHasContent = !windowList.isEmpty();
+    setDefocused();
 }
 
-void DesktopView::setGeometry(const QRectF &rect)
+void DesktopView::setDefocused()
 {
-    MWidgetView::setGeometry(rect);
-    // Set the viewports to the size of the desktop
-    appletSpaceViewport->setMinimumSize(rect.size());
-    appletSpaceViewport->setMaximumSize(rect.size());
+    bool defocused = switcherHasContent || launcherVisible;
+    foreach (MDesktopBackgroundExtensionInterface *backgroundExtension, backgroundExtensions) {
+        backgroundExtension->setDefocused(defocused);
+    }
 }
 
 void DesktopView::update()
--- src/home/desktopview.h
+++ src/home/desktopview.h
@@ -24,6 +24,7 @@
 #include "desktopmodel.h"
 #include "desktopstyle.h"
 #include "mdesktopbackgroundextensioninterface.h"
+#include "windowinfo.h"
 
 class Desktop;
 class Switcher;
@@ -32,8 +33,7 @@
 class Launcher;
 class NotificationArea;
 class QGraphicsLinearLayout;
-class AppletSpace;
-class MModalSceneWindow;
+class MSceneWindow;
 class MPannableViewport;
 class MOverlay;
 class MApplicationExtensionArea;
@@ -43,9 +43,7 @@
 
 /*!
  * The desktop view draws a background for the desktop and manages layouts
- * related to the desktop. The applets are inside a flow layout, which in
- * turn is inside a main layout. In addition to this the main layout
- * contains a button for displaying the applet inventory.
+ * related to the desktop.
  */
 class DesktopView : public MWidgetView, public MDesktopInterface
 {
@@ -70,17 +68,19 @@
     virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0);
 #endif
     virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
-    virtual void setGeometry(const QRectF &rect);
     virtual void update();
     virtual M::OrientationAngle orientationAngle();
     //! \reimp_end
 
 private slots:
-    //! Shows the launcher if it is not visible, hides it otherwise
-    void toggleLauncher();
+    //! Hides the launcher if applicable, based on the top most window
+    void updateLauncherVisiblity(const QList<WindowInfo> &windowList);
+
+    //! Sets whether the switcher has content or not based on the window list
+    void setSwitcherHasContent(const QList<WindowInfo> &windowList);
 
-    //! Shows the applet space if it is not visible, hides it otherwise
-    void toggleAppletSpace();
+    //! Toggles the launcher visibility
+    void toggleLauncher();
 
     /*!
      * Registers a desktop background extension.
@@ -112,8 +112,7 @@
 #endif
 
 private:
-
-     /*!
+    /*!
      * \brief Shows the application launcher
      */
     void showLauncher();
@@ -124,6 +123,16 @@
     void hideLauncher();
 
     /*!
+     * \brief Rearranges the Z order of the scene window
+     */
+    void setSceneWindowOrder();
+
+    /*!
+     * \brief Lets the background extensions know whether the desktop should be defocused or not
+     */
+    void setDefocused();
+
+    /*!
      * Creates a launcher data store.
      *
      * \return an initialized launcher data store
@@ -136,14 +145,23 @@
     //! The switcher widget
     Switcher *switcher;
 
+    //! Scene window for the switcher
+    MSceneWindow *switcherWindow;
+
+    //! Whether the switcher has content in it
+    bool switcherHasContent;
+
     //! Data store to store the launcher and quick launch bar item locations to
     LauncherDataStore *launcherDataStore;
 
     //! Application launcher
     Launcher *launcher;
 
-    //! scene window for the launcher
-    MModalSceneWindow *launcherWindow;
+    //! Scene window for the launcher
+    MSceneWindow *launcherWindow;
+
+    //! Whether the launcher is visible or not
+    bool launcherVisible;
 
     //! The quick launch bar
     QuickLaunchBar *quickLaunchBar;
@@ -151,15 +169,6 @@
     //! Scene window for the quick launch bar
     MOverlay *quickLaunchBarWindow;
 
-    //! The applet space
-    AppletSpace *appletSpace;
-
-    //! Scene window for the applet space
-    MModalSceneWindow *appletSpaceWindow;
-
-    //! Pannable viewport in which the applet space is displayed
-    MPannableViewport *appletSpaceViewport;
-
     //! Application extension support for desktop background drawing
     MApplicationExtensionArea *backgroundExtensionArea;
 
--- src/home/files.pri
+++ src/home/files.pri
@@ -2,10 +2,6 @@
 HEADERS += homeapplication.h \
     windowinfo.h \
     home.h \
-    appletspace.h \
-    appletspaceview.h \
-    appletspacemodel.h \
-    appletspacestyle.h \
     desktop.h \
     desktopmodel.h \
     desktopview.h \
@@ -15,8 +11,11 @@
     launcherview.h \
     launchermodel.h \
     launcherstyle.h \
+    launcheraction.h \
     launcherbutton.h \
+    launcherbuttonview.h \
     launcherbuttonmodel.h \
+    launcherbuttonstyle.h \
     pagedpanning.h \
     pagedviewport.h \
     pagedviewportstyle.h \
@@ -33,7 +32,6 @@
     switcherbuttonmodel.h \
     switcherbuttonview.h \
     switcherbuttonstyle.h \
-    x11helper.h \
     x11wrapper.h \
     launcherpage.h \
     launcherpageview.h \
@@ -49,14 +47,14 @@
 SOURCES += homeapplication.cpp \
     windowinfo.cpp \
     home.cpp \
-    appletspace.cpp \
-    appletspaceview.cpp \
     desktop.cpp \
     desktopview.cpp \
     mainwindow.cpp \
     launcher.cpp \
     launcherview.cpp \
+    launcheraction.cpp \
     launcherbutton.cpp \
+    launcherbuttonview.cpp \
     pagedpanning.cpp \
     pagedviewport.cpp \
     pagedviewportview.cpp \
@@ -66,7 +64,6 @@
     switcherview.cpp \
     switcherbutton.cpp \
     switcherbuttonview.cpp \
-    x11helper.cpp \
     x11wrapper.cpp \
     launcherpage.cpp \
     launcherpageview.cpp \
@@ -75,9 +72,7 @@
     pagepositionindicator.cpp \
     homescreenservice.cpp \
     homescreenadaptor.cpp
-MODEL_HEADERS += appletspacemodel.h \
-    appletspacemodel.h \
-    desktopmodel.h \
+MODEL_HEADERS += desktopmodel.h \
     launcherbuttonmodel.h \
     launchermodel.h \
     quicklaunchbarmodel.h \
@@ -85,10 +80,9 @@
     switchermodel.h \
     launcherpagemodel.h \
     pagepositionindicatormodel.h
-STYLE_HEADERS += appletspacestyle.h \
-    appletspacestyle.h \
-    desktopstyle.h \
+STYLE_HEADERS += desktopstyle.h \
     launcherstyle.h \
+    launcherbuttonstyle.h \
     launcherpagestyle.h \
     quicklaunchbarstyle.h \
     switcherbuttonstyle.h \
--- src/home/home.pro
+++ src/home/home.pro
@@ -40,10 +40,7 @@
     meegotouch
 PKGCONFIG += xcomposite \
     contextsubscriber-1.0 \
-#    ContentManagerSearchIf
-
-# Support for deprecated DuiValueSpace. Remove this define when new ContextSubscriber is used.
-DEFINES += MVALUESPACE_USE_DEPRECATED
+    contentaction-0.1
 
 QMAKE_EXTRA_TARGETS += check
 check.commands = $$system(true)
--- src/home/homeapplication.cpp
+++ src/home/homeapplication.cpp
@@ -16,7 +16,6 @@
 ** of this file.
 **
 ****************************************************************************/
-
 #include "homescreenservice.h"
 #include "homescreenadaptor.h"
 
@@ -29,7 +28,6 @@
 #include "homeapplication.h"
 #include "mainwindow.h"
 #include "x11wrapper.h"
-#include "x11helper.h"
 
 static const QString MEEGO_CORE_HOME_SCREEN_SERVICE_NAME="com.meego.core.HomeScreen";
 static const QString MEEGO_CORE_HOME_SCREEN_OBJECT_PATH ="/homescreen";
@@ -85,18 +83,11 @@
 
     // Get X11 Atoms for different window types
     Display *dpy = QX11Info::display();
+
     windowTypeAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
-    windowTypeNormalAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
-    windowTypeDesktopAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
-    windowTypeNotificationAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
-    windowTypeCallAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_CALL", False);
-    windowTypeDockAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
-    windowTypeDialogAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
-    windowTypeMenuAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
     clientListAtom = X11Wrapper::XInternAtom(dpy, "_NET_CLIENT_LIST", False);
     stackedClientListAtom = X11Wrapper::XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
     closeWindowAtom = X11Wrapper::XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
-    skipTaskbarAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
     windowStateAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_STATE", False);
     netWindowNameAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_NAME", False);
     windowNameAtom = X11Wrapper::XInternAtom(dpy, "WM_NAME", False);
@@ -139,26 +130,11 @@
     }
 }
 
-void HomeApplication::launchContentSearchService()
-{
-    /*
-    if (contentSearchIf.isValid()) {
-        contentSearchIf.launch("");
-    }
-    */
-}
-
 bool HomeApplication::x11EventFilter(XEvent *event)
 {
-    if (event->type == PropertyNotify &&
-        event->xproperty.window == DefaultRootWindow(QX11Info::display())) {
-        if (event->xproperty.atom == clientListAtom) {
-            // The _NET_CLIENT_LIST property of the root window has changed so update the window list
-            updateWindowList();
-            return true;
-        } else if (event->xproperty.atom == stackedClientListAtom) {
-            QList<WindowInfo> windowList = filterWindows(stackedClientListAtom);
-            emit windowStackingChanged(windowList);
+    if (event->type == PropertyNotify && event->xproperty.window == DefaultRootWindow(QX11Info::display())) {
+        if (event->xproperty.atom == stackedClientListAtom) {
+            updateWindowMapping();
             return true;
         }
     } else if (event->type == VisibilityNotify) {
@@ -183,14 +159,15 @@
     } else if (event->type == ClientMessage && event->xclient.message_type == closeWindowAtom) {
         // A _NET_CLOSE_WINDOW message was caught so a window is being closed; add it to windows being closed list and update the window list
         if (!windowsBeingClosed.contains(event->xclient.window)) {
-            windowsBeingClosed.append(event->xclient.window);
+            windowsBeingClosed.insert(event->xclient.window);
         }
-        updateWindowList();
+        updateWindowMapping();
         return true;
     } else if (event->type == PropertyNotify &&
                (event->xproperty.atom == windowTypeAtom || event->xproperty.atom == windowStateAtom)) {
-        // Window types changed so update the window list
-        updateWindowList();
+
+        updateWindowProperties(event->xproperty.window);
+
         return true;
     } else if (event->type == PropertyNotify &&
                (event->xproperty.atom == windowNameAtom || event->xproperty.atom == netWindowNameAtom)) {
@@ -203,29 +180,32 @@
 
 void HomeApplication::updateWindowTitle(Window window)
 {
-    Display *dpy = QX11Info::display();
-    XTextProperty windowTitleDataProperty;
-
-    int result = X11Wrapper::XGetTextProperty(dpy, window, &windowTitleDataProperty, netWindowNameAtom);
-
-    if (result == 0) {
-        result = X11Wrapper::XGetWMName(dpy, window, &windowTitleDataProperty);
-    }
-
-    if (result != 0) {
-        QString title(QString::fromUtf8((const char *)windowTitleDataProperty.value));
-        emit windowTitleChanged(window, title);
+    bool updated = windowMap[window].updateWindowTitle();
+    if (updated) {
+        emit windowTitleChanged(window, windowMap[window].title());
     }
 }
 
-void HomeApplication::updateWindowList()
+void HomeApplication::updateWindowProperties(Window window)
 {
-    QList<WindowInfo> windowList = filterWindows(clientListAtom);
-    // Signal listeners that the window list has changed
-    emit windowListUpdated(windowList);
+    if (windowMap.contains(window)) {
+        WindowInfo windowInfo = windowMap[window];
+        bool wasApplication = isApplicationWindow(windowInfo);
+        windowInfo.updateWindowProperties();
+        bool isApplication = isApplicationWindow(windowInfo);
+        if (wasApplication != isApplication) {
+            // If the window has changed from an app window to some thing else or wise versa
+            if (isApplication) {
+                applicationWindows.append(windowInfo);
+            } else {
+                applicationWindows.removeOne(windowInfo);
+            }
+            emit windowListUpdated(applicationWindows);
+        }
+    }
 }
 
-QList<WindowInfo> HomeApplication::filterWindows(Atom clientListAtom)
+void HomeApplication::updateWindowMapping()
 {
     // Get a list of all windows
     Display *dpy = QX11Info::display();
@@ -234,105 +214,99 @@
     int actualFormat;
     unsigned long numWindowItems, bytesLeft;
     unsigned char *windowData = NULL;
-    int result = X11Wrapper::XGetWindowProperty(dpy, DefaultRootWindow(dpy), clientListAtom,
+    Status result = X11Wrapper::XGetWindowProperty(dpy, DefaultRootWindow(dpy), stackedClientListAtom,
                                                 0, 0x7fffffff, False, XA_WINDOW,
                                                 &actualType, &actualFormat, &numWindowItems, &bytesLeft, &windowData);
-    QList<WindowInfo> windowList;
+
     if (result == Success && windowData != None) {
-        // Go through the list of all windows
-        QList<Window> windowsStillBeingClosed;
+        // We need to keep the stacking order of the windows -> hence the list
+        QList<Window> newWindowList;
         Window *wins = (Window *)windowData;
         for (unsigned int i = 0; i < numWindowItems; i++) {
+            result = X11Wrapper::XGetWindowAttributes(dpy, wins[i], &wAttributes);
             // The windows that are bigger than 0x0, are Input/Output windows and are not unmapped are interesting
-            if (X11Wrapper::XGetWindowAttributes(dpy, wins[i],
-                                                 &wAttributes) != 0 && wAttributes.width > 0 &&
-                    wAttributes.height > 0 && wAttributes.c_class == InputOutput &&
-                    wAttributes.map_state != IsUnmapped) {
-                unsigned char *typeData = NULL;
-                unsigned long numTypeItems;
-
-                // Get the window type
-                result = X11Wrapper::XGetWindowProperty(dpy, wins[i], windowTypeAtom, 0L, 16L, False, XA_ATOM,
-                                                        &actualType, &actualFormat, &numTypeItems, &bytesLeft, &typeData);
-
-                if (result == Success) {
-                    Atom *type = (Atom *)typeData;
-
-                    // Only "normal" windows should be included in the window list
-                    bool includeInWindowList = false;
-                    WindowInfo::WindowPriority priority = WindowInfo::Normal;
-                    // plain X windows like xclock and xev have no type
-                    if (numTypeItems == 0) {
-                        includeInWindowList = true;
-                    }
-                    for (unsigned int n = 0; n < numTypeItems; n++) {
-                        // "Desktop", "Notification", "Dock", "Dialog" and "Menu" windows should never be included in the window list
-                        if (type[n] == windowTypeDesktopAtom || type[n] == windowTypeNotificationAtom || type[n] == windowTypeDockAtom || type[n] == windowTypeDialogAtom || type[n] == windowTypeMenuAtom) {
-                            includeInWindowList = false;
-                            break;
-                        }
-                        if (type[n] == windowTypeNormalAtom) {
-                            includeInWindowList = true;
-                        } else if (type[n] == windowTypeCallAtom) {
-                            includeInWindowList = true;
-                            priority = WindowInfo::Call;
-                        }
-                    }
-
-                    if (includeInWindowList) {
-                        // If _NET_WM_STATE has the _NET_WM_STATE_SKIP_TASKBAR set, don't include the window to the list
-                        if (X11Helper::getNetWmState(dpy, wins[i]).contains(skipTaskbarAtom)) {
-                            includeInWindowList = false;
-                        }
-                    }
-
-                    if (includeInWindowList) {
-                        Pixmap pixmap = NULL;
-                        XTextProperty textProperty;
-                        QString title;
-
-                        // Tell X that changes in the visibility of the window
-                        // and in the properties of the window are interesting
-                        X11Wrapper::XSelectInput(dpy, wins[i],
-                                                 VisibilityChangeMask
-                                                 | PropertyChangeMask);
-
-                        // Get window title
-                        if (X11Wrapper::XGetWMName(dpy, wins[i], &textProperty) != 0) {
-                            title = QString((const char *)(textProperty.value));
-                            X11Wrapper::XFree(textProperty.value);
-                        }
-
-                        // Get window icon
-                        XWMHints *wmhints = X11Wrapper::XGetWMHints(dpy, wins[i]);
-                        if (wmhints != NULL) {
-                            pixmap = wmhints->icon_pixmap;
-                            X11Wrapper::XFree(wmhints);
-                        }
-
-                        if (!windowsBeingClosed.contains(wins[i])) {
-                            // Add a window to the list
-                            windowList.append(WindowInfo(title, wins[i], wAttributes, pixmap, priority));
-                        } else {
-                            // The window is still being closed and can not be removed from the windows being closed list
-                            windowsStillBeingClosed.append(wins[i]);
-                        }
-                    }
+            if (result != 0 &&
+                wAttributes.width > 0 && wAttributes.height > 0 &&
+                wAttributes.c_class == InputOutput &&
+                wAttributes.map_state != IsUnmapped) {
+                newWindowList.append(wins[i]);
+            }
+        }
+        QSet<Window> newWindowSet = newWindowList.toSet() - windowsBeingClosed;
 
-                    X11Wrapper::XFree(typeData);
-                }
+        QSet<Window> oldWindowSet = windowMap.keys().toSet();
+
+        QSet<Window> closedWindowSet = oldWindowSet - newWindowSet;
+        windowsBeingClosed -= closedWindowSet;
+
+        QSet<Window> openedWindowSet = newWindowSet - oldWindowSet;
+
+        bool added = createWindowInfos(openedWindowSet);
+        bool removed = removeWindowInfos(closedWindowSet);
+        if (added || removed) {
+            emit windowListUpdated(applicationWindows);
+        }
+        windowsBeingClosed -= closedWindowSet;
+
+        QList<WindowInfo> stackingWindowList;
+        foreach (Window w, newWindowList) {
+            if (!windowsBeingClosed.contains(w)) {
+                stackingWindowList.append(windowMap.value(w));
             }
         }
+        emit windowStackingOrderChanged(stackingWindowList);
+    }
+}
 
-        X11Wrapper::XFree(wins);
+bool HomeApplication::createWindowInfos(QSet<Window> openedWindowSet)
+{
+    Display *dpy = QX11Info::display();
+    bool appWindowsAppeared = false;
+    foreach(Window w, openedWindowSet) {
+        WindowInfo newWindow(w);
+        windowMap.insert(w, newWindow);
+        if (MainWindow::instance() != NULL && MainWindow::instance()->winId() != w) {
+            X11Wrapper::XSelectInput(dpy, w, VisibilityChangeMask | PropertyChangeMask);
+        }
 
-        // Remove all windows that have now been closed from the windows being closed list
-        for (int i = windowsBeingClosed.count() - 1; i >= 0; i--) {
-            Window window = windowsBeingClosed.at(i);
-            if (!windowsStillBeingClosed.contains(window)) {
-                windowsBeingClosed.removeAt(i);
+        if (isApplicationWindow(newWindow)) {
+            applicationWindows.append(newWindow);
+            appWindowsAppeared = true;
+        }
+    }
+    return appWindowsAppeared;
+}
+
+bool HomeApplication::removeWindowInfos(QSet<Window> closedWindowSet)
+{
+    bool appWindowsDisappeared = false;
+    foreach(Window w, closedWindowSet) {
+        if (windowMap.contains(w)) {
+            WindowInfo removedWindow = windowMap.take(w);
+            if (applicationWindows.removeOne(removedWindow)) {
+                appWindowsDisappeared = true;
             }
         }
     }
-    return windowList;
+    return appWindowsDisappeared;
+}
+
+bool HomeApplication::isApplicationWindow(const WindowInfo &wi)
+{
+    // Initialize the sets here, as the atom values in WindowInfo
+    // might not have been set earlier
+    if (excludeAtoms.count() == 0) {
+        excludeAtoms.insert(WindowInfo::DesktopAtom);
+        excludeAtoms.insert(WindowInfo::MenuAtom);
+        excludeAtoms.insert(WindowInfo::DockAtom);
+        excludeAtoms.insert(WindowInfo::DialogAtom);
+        excludeAtoms.insert(WindowInfo::NotificationAtom);
+        excludeAtoms.insert(WindowInfo::SkipTaskbarAtom);
+    }
+
+    QSet<Atom> excludeSet;
+    excludeSet += wi.types().toSet();
+    excludeSet += wi.states().toSet();
+
+    return excludeSet.intersect(excludeAtoms).isEmpty();
 }
--- src/home/homeapplication.h
+++ src/home/homeapplication.h
@@ -21,9 +21,10 @@
 #define HOMEAPPLICATION_H_
 
 #include <MApplication>
-//#include <contentsearchif.h>
 #include "windowinfo.h"
 #include <QTimer>
+#include <QMap>
+#include <QSet>
 
 class MainWindow;
 class HomeScreenService;
@@ -50,12 +51,6 @@
      */
     ~HomeApplication();
 
-public slots:
-    /*!
-     * Launches content search service
-     */
-    void launchContentSearchService();
-
 signals:
 
     /*!
@@ -69,6 +64,11 @@
     void windowListUpdated(const QList<WindowInfo> &windowList);
 
     /*!
+     * \brief A signal to indicate that the window ordering has changed
+     */
+    void windowStackingOrderChanged(const QList<WindowInfo> &windowList);
+
+    /*!
      * \brief A signal for notifying that the window visibility has changed
      */
     void windowVisibilityChanged(Window window);
@@ -78,14 +78,6 @@
      */
     void windowTitleChanged(Window window, const QString &title);
 
-    /*!
-     * \brief A signal to indicate that the window stacking order has changed.
-     * the window list will only contain windows that the homeapplication is
-     * interrested in, as an example it will not contain desktop or
-     * notification windows
-     */
-    void windowStackingChanged(const QList<WindowInfo> &windowList);
-
 #ifdef BENCHMARKS_ON
     void startBenchmarking();
     void stopBenchmarking();
@@ -107,52 +99,57 @@
     void sendStartupNotifications();
 
 private:
-    // X11 Atoms for different window types
+    // X11 Atoms
     Atom windowTypeAtom;
-    Atom windowTypeNormalAtom;
-    Atom windowTypeDesktopAtom;
-    Atom windowTypeNotificationAtom;
-    Atom windowTypeDockAtom;
-    Atom windowTypeDialogAtom;
-    Atom windowTypeMenuAtom;
-    Atom windowTypeCallAtom;
     Atom clientListAtom;
     Atom stackedClientListAtom;
     Atom closeWindowAtom;
-    Atom skipTaskbarAtom;
     Atom windowStateAtom;
     Atom netWindowNameAtom;
     Atom windowNameAtom;
 
-    //! Content search service interface. Used to launch the content search service.
-    //ContentSearchIf contentSearchIf;
-
     //! A list of windows that are being closed
-    QList<Window> windowsBeingClosed;
+    QSet<Window> windowsBeingClosed;
+
+    /*!
+     * Gets the current client window list from X and filters it based on
+     *  - Windows that are bigger than 0x0, are Input/Output windows, are not unmapped and type includes Normal are included. Additionally:
+     *  - Windows that have a type Notification or Desktop are not included.
+     *  - Windows that have the "skip taskbar" state flag set, are not included.
+     *  - Windows that are non application windows, such as desktop, menu, notification.
+     */
+    void updateWindowMapping();
+
+    /*!
+     * Updates the window properties changes.
+     * \param window The window to update.
+     */
+    void updateWindowProperties(Window window);
 
+    /*!
+     * Helper method to create a \c WindowInfos into the current mapping
+     * \param openedWindowSet A set of new windows
+     * \return true if application windows were added
+     */
+    bool createWindowInfos(QSet<Window> openedWindowSet);
 
     /*!
-     * Update the title of the given window from X.
+     * Update the title of the given window and emit \c windowTitleChanged
+     * \param window The X window to update
      */
     void updateWindowTitle(Window window);
 
     /*!
-     * Retreives the filtered window list (see HomeApplication::filterWindows)
-     * and emits the windowListUpdated with the current window list as the
-     * parameter.
+     * Helper method to remove a \c WindowInfos from the current mapping
+     * \param closedWindowSet A set of closed windows
+     * \return true if application windows were removed
      */
-    void updateWindowList();
+    bool removeWindowInfos(QSet<Window> closedWindowSet);
 
     /*!
-     * Gets the current client window list from X and filters it based on
-     *  - The given \c Atom
-     *  - Windows that are bigger than 0x0, are Input/Output windows, are not unmapped and type includes Normal are included. Additionally:
-     *  - Windows that have a type Notification or Desktop are not included.
-     *  - Windows that have the "skip taskbar" state flag set, are not included.
-     * \param atom The atom that fill be used to filter teh window list
-     * \return The filtered window list
+     * Helper method to check if the window is an applciation window
      */
-    QList<WindowInfo> filterWindows(Atom atom);
+    bool isApplicationWindow(const WindowInfo &window);
 
     //! Flag that indicates whether duihome was started by upstart or not
     bool upstartMode;
@@ -162,6 +159,16 @@
 
     //! Implementations for com.meego.core.HomeScreen interface.
     HomeScreenService *homeScreenService;
+
+    //! Mapping of the current X windows
+    QMap<Window, WindowInfo> windowMap;
+
+    //! List of application windows
+    QList<WindowInfo> applicationWindows;
+
+    //! A set of window type atoms that are used to finlter the application windows
+    QSet<Atom> excludeAtoms;
+
 };
 
 #endif /* HOMEAPPLICATION_H_ */
--- src/home/launcher.cpp
+++ src/home/launcher.cpp
@@ -17,8 +17,6 @@
 **
 ****************************************************************************/
 
-#include <MApplicationIfProxy>
-#include <MDesktopEntry>
 #include "launcher.h"
 #include "launcherbutton.h"
 #include "launcherdatastore.h"
@@ -38,30 +36,6 @@
 {
 }
 
-bool Launcher::startApplication(const QString &application)
-{
-    if (!QProcess::startDetached(application)) {
-        qWarning() << "Failed to start application:" << application;
-        return false;
-    } else {
-        return true;
-    }
-}
-
-bool Launcher::startMApplication(const QString &serviceName)
-{
-    MApplicationIfProxy mApplicationIfProxy(serviceName, NULL);
-
-    if (mApplicationIfProxy.connection().isConnected()) {
-        mApplicationIfProxy.launch();
-        return true;
-    } else {
-        qWarning() << "Could not launch" << serviceName;
-        qWarning() << "DBus not connected?";
-        return false;
-    }
-}
-
 void Launcher::updatePagesFromDataStore()
 {
     // Stop listening to dataStoreChanged() and start listening to individual updates instead.
@@ -241,6 +215,11 @@
     return page;
 }
 
+void Launcher::setFirstPage()
+{
+    emit focusToFirstPageRequested();
+}
+
 int Launcher::pageNumber(const QString &desktopFileEntry)
 {
     QString desktopFile = QString(desktopFileEntry);
--- src/home/launcher.h
+++ src/home/launcher.h
@@ -79,22 +79,6 @@
      */
     virtual ~Launcher();
 
-    /*!
-     * Starts an application.
-     *
-     * \param application the application to be started
-     * \return \c true if starting succeeded, \c false otherwise
-     */
-    static bool startApplication(const QString &application);
-
-    /*!
-     * Starts a M application.
-     *
-     * \param serviceName the service name of the application to be started
-     * \return \c true if starting succeeded, \c false otherwise
-     */
-    static bool startMApplication(const QString &serviceName);
-
 signals:
     /*!
      * Signal sent when a launcher button was clicked.
@@ -108,6 +92,11 @@
      */
     void panningRequested(uint page);
 
+    /*!
+     * Signal to request moving launcher focus to first page
+     */
+    void focusToFirstPageRequested();
+
 public slots:
 
     /*!
@@ -122,6 +111,11 @@
      */
     int panToPage(const QString &desktopFileEntry);
 
+    /*!
+     * Set launcher to show first page
+     */
+    void setFirstPage();
+
 private slots:
 
     /*!
@@ -228,6 +222,11 @@
 
     //! Whether the launcher has been initialized or not
     bool initialized;
+
+
+#ifdef UNIT_TEST
+    friend class Ut_Launcher;
+#endif
 };
 
 #endif /* LAUNCHER_H */
--- src/home/launcheraction.cpp
+++ src/home/launcheraction.cpp
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include "launcheraction.h"
+
+LauncherAction::LauncherAction()
+    : Action()
+{
+}
+
+LauncherAction::LauncherAction(const QString& desktopEntry)
+    : Action(Action::defaultActionForFile(desktopEntry, "application/x-desktop"))
+{
+}
+
+bool operator==(const LauncherAction &a, const LauncherAction &b)
+{
+    return 
+        a.isValid() && b.isValid() &&
+        a.name() == b.name() &&
+        a.localizedName() == b.localizedName() &&
+        a.icon() == b.icon();
+}
+
+bool operator!=(const LauncherAction &a, const LauncherAction &b)
+{
+    return !(a == b);
+}
--- src/home/launcheraction.h
+++ src/home/launcheraction.h
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef LAUNCHERACTION_H
+#define LAUNCHERACTION_H
+
+#include <contentaction.h>
+
+/*!
+ * A convenience wrapper around libcontentaction's ContenAction::Action.
+ * The object is used to turn .desktop files into objects that take care
+ * of invoking of the default action (D-Bus method call, execution of
+ * a binary, etc) specified in these .desktop files.
+ *
+ * Instantiated with a valid .desktop file path, the object provides a
+ * trigger() method that asynchronously trigers the default action for that
+ * .desktop file.
+ */
+class LauncherAction : public ContentAction::Action
+{
+    public:
+        /*!
+         * Constructs an empty LauncherAction object.
+         */
+        LauncherAction();
+
+        /*!
+         * Constructs a LauncherAction object from a given .desktop file.
+         *
+         * \param dekstopEntry Path to the .desktop file to initialize
+         * the action for.
+         */
+        LauncherAction(const QString& dekstopEntry);
+};
+
+//! Comparison operator for LauncherAction objects
+bool operator==(const LauncherAction &, const LauncherAction &);
+//! The reverse of the comparison operator for LauncherAction objects
+bool operator!=(const LauncherAction &, const LauncherAction &);
+
+#endif
--- src/home/launcherbutton.cpp
+++ src/home/launcherbutton.cpp
@@ -18,19 +18,24 @@
 ****************************************************************************/
 
 #include "launcherbutton.h"
+#include "launcheraction.h"
 #include "launcher.h"
 #include <MDesktopEntry>
+#include <QDateTime>
+#include <QFileInfo>
+#include <QApplication>
+
+bool LauncherButton::launching = false;
 
 LauncherButton::LauncherButton(MWidget *parent) : MButton(parent, new LauncherButtonModel)
 {
-    // Connect the button clicked signal to launch application slot.
-    connect(this, SIGNAL(clicked()), this, SLOT(launch()));
+    init();
 }
 
-LauncherButton::LauncherButton(const QString &desktopEntryPath, MWidget *parent) : MButton(parent, new LauncherButtonModel)
+LauncherButton::LauncherButton(const QString &desktopEntryPath, MWidget *parent) :
+        MButton(parent, new LauncherButtonModel)
 {
-    // Connect the button clicked signal to launch application slot.
-    connect(this, SIGNAL(clicked()), this, SLOT(launch()));
+    init();
 
     updateFromDesktopEntry(desktopEntryPath);
 }
@@ -39,24 +44,24 @@
 {
 }
 
-void LauncherButton::setTargetType(const QString &type)
+void LauncherButton::init()
 {
-    model()->setTargetType(type);
-}
+    // When the button is clicked the related object should be launched
+    connect(this, SIGNAL(clicked()), this, SLOT(launch()));
 
-QString LauncherButton::targetType() const
-{
-    return model()->targetType();
+    // When the progress indicator timer times out the progress indicator should be hidden
+    progressIndicatorTimeoutTimer.setSingleShot(true);
+    connect(&progressIndicatorTimeoutTimer, SIGNAL(timeout()), this, SLOT(hideProgressIndicator()));
 }
 
-void LauncherButton::setTarget(const QString &target)
+void LauncherButton::setAction(const LauncherAction &action)
 {
-    model()->setTarget(target);
+    model()->setAction(action);
 }
 
-QString LauncherButton::target() const
+LauncherAction LauncherButton::action() const
 {
-    return model()->target();
+    return model()->action();
 }
 
 QString LauncherButton::desktopEntry() const
@@ -66,42 +71,95 @@
 
 void LauncherButton::launch()
 {
-    if (targetType() == "Application") {
-        Launcher::startApplication(target());
-    } else if (targetType() == "Service") {
-        Launcher::startMApplication(target());
+    if (!launching) {
+        launching = true;
+        model()->setShowProgressIndicator(true);
+
+        connect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), this, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &)));
+
+        action().trigger();
+
+        progressIndicatorTimeoutTimer.start();
+    }
+}
+
+void LauncherButton::hideProgressIndicator()
+{
+    launching = false;
+    model()->setShowProgressIndicator(false);
+
+    if (progressIndicatorTimeoutTimer.isActive()) {
+        progressIndicatorTimeoutTimer.stop();
+    }
+
+    disconnect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), this, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &)));
+}
+
+void LauncherButton::hideProgressIndicatorIfObscured(const QList<WindowInfo> &windowList)
+{
+    if (!windowList.isEmpty()) {
+        const QList<Atom>& windowTypes = windowList.last().types();
+        if (!windowTypes.contains(WindowInfo::NotificationAtom) &&
+            !windowTypes.contains(WindowInfo::DesktopAtom) &&
+            !windowTypes.contains(WindowInfo::DialogAtom) &&
+            !windowTypes.contains(WindowInfo::MenuAtom)) {
+            hideProgressIndicator();
+        }
     }
 }
 
+void LauncherButton::retranslateUi()
+{
+    if (!desktopEntry().isNull()) {
+        setText(action().localizedName());
+    }
+    MButton::retranslateUi();
+}
+
 void LauncherButton::updateFromDesktopEntry(const QString &desktopEntryPath)
 {
     // only update if not initialized yet or if from the same desktop entry
-    if (model()->desktopEntryFile().isEmpty() || desktopEntryPath == model()->desktopEntryFile()) {
-        MDesktopEntry entry(desktopEntryPath);
-        setTargetType(entry.type());
-        setText(entry.name());
+    if (desktopEntry().isNull()
+        || desktopEntryPath == desktopEntry()) {
 
-        if (!entry.icon().isEmpty()) {
-            setIconID(entry.icon());
-        } else {
-            // FIXME: change to use correct default icon id when available
-            // as incorrect id icon-Application-Default will load default icon
-            // (at the moment default icon seems to be icon-l-video)
-            setIconID("icon-Application-Default");
-        }
+        LauncherAction action(desktopEntryPath);
 
-        // Set target based on type
-        if (entry.type() == "Application") {
-            QString thisXMaemoService = entry.xMaemoService();
+        setText(action.localizedName());
+        updateIcon(action);
 
-            if (thisXMaemoService.isEmpty()) {
-                setTarget(entry.exec());
+        model()->setDesktopEntryFile(desktopEntryPath);
+        setAction(action);
+    }
+}
+
+void LauncherButton::updateIcon(const LauncherAction& action)
+{
+    QString icon = action.icon();
+
+    if (!icon.isEmpty()) {
+        if (QFileInfo(icon).isAbsolute()) {
+            setIcon(QIcon(icon));
+        } else {
+            if (QIcon::hasThemeIcon(icon)) {
+                setIcon(QIcon::fromTheme(icon));
             } else {
-                setTarget(thisXMaemoService);
-                setTargetType("Service");
+                setIconID(icon);
             }
         }
-
-        model()->setDesktopEntryFile(entry.fileName());
+    } else {
+        // FIXME: change to use correct default icon id when available
+        // as incorrect id icon-Application-Default will load default icon
+        // (at the moment default icon seems to be icon-l-video)
+        setIconID("icon-Application-Default");
     }
 }
+
+bool LauncherButton::isInProgress() const
+{
+    return model()->showProgressIndicator();
+}
+
+void LauncherButton::setProgressIndicatorTimeout(int timeout)
+{
+    progressIndicatorTimeoutTimer.setInterval(timeout);
+}
--- src/home/launcherbutton.h
+++ src/home/launcherbutton.h
@@ -20,10 +20,13 @@
 #ifndef LAUNCHERBUTTON_H
 #define LAUNCHERBUTTON_H
 
+#include <QTimer>
 #include <MButton>
 #include "launcherbuttonmodel.h"
+#include "windowinfo.h"
 
 class MDesktopEntry;
+class LauncherAction;
 
 /*!
  * Button widget that can launch an application when its being clicked.
@@ -40,6 +43,7 @@
     M_CONTROLLER(LauncherButton)
 
     Q_PROPERTY(QString desktopEntryPath READ desktopEntry)
+    Q_PROPERTY(bool inProgress READ isInProgress)
 
 public:
     /*!
@@ -63,34 +67,20 @@
     virtual ~LauncherButton();
 
     /*!
-     * \brief Sets the type of the object to be launched.
+     * \brief Sets the action to launch the application described by the
+     * desktop file. 
      *
-     * \param type Type of the object to be launched
+     * \param action The action to launch the application
      */
-    void setTargetType(const QString &type);
+    void setAction(const LauncherAction &action);
 
     /*!
-     * \brief Returns the type of the target launched by this button widget.
+     * \brief Returns the action to launch the application described by the
+     * desktop file
      *
-     * \return Type of the object to be launched
+     * \return The action to launch the application
      */
-    QString targetType() const;
-
-    /*!
-     * \brief Sets the target to be launched when this button widget
-     * instance is clicked.
-     *
-     * \param target Full path to the application that will be launched.
-     */
-    void setTarget(const QString &target);
-
-    /*!
-     * \brief Returns full path to the target file launched by this button
-     * widget.
-     *
-     * \return Full path to the application file
-     */
-    QString target() const;
+    LauncherAction action() const;
 
     /*!
      * Returns the file name of the desktop entry where this launcher button was constructed from.
@@ -104,26 +94,61 @@
      */
     void updateFromDesktopEntry(const QString &desktopEntryPath);
 
+    /*!
+     * Handles the language change notification and propagets is to MButton.
+     */
+    void retranslateUi();
+
+    /*!
+     * Returns whether the object represented by this launcher button is being launched.
+     * \return \c true if the object represented by this launcher button is being launched, \c false otherwise
+     */
+    bool isInProgress() const;
+
+    /*!
+     * Sets the timeout of the progress indicator in milliseconds
+     * \param timeout the timeout of the progress indicator in milliseconds
+     */
+    void setProgressIndicatorTimeout(int timeout);
+
 private slots:
     /*!
-     * Attempts to launch the configured application.
+     * Attempts to launch the configured object.
      */
     void launch();
 
-signals:
     /*!
-     * \brief A signal for notifying that an object of type Application has been launched
-     *
-     * \param application the name of the application
+     * Hides the progress indicator.
+     */
+    void hideProgressIndicator();
+
+    /*!
+     * Hides the progress indicator if the window list contains only normal windows
      */
-    void applicationLaunched(const QString &application);
+    void hideProgressIndicatorIfObscured(const QList<WindowInfo> &windowList);
 
+private:
     /*!
-     * \brief A signal for notifying that an object of type Application that has an X-Maemo-Service has been launched
+     * Initializes the launcher button.
+     */
+    void init();
+
+    /*!
+     * Updates the icon based on a launcher action
      *
-     * \param service the name of the dbus service to launch
+     * \param action the LauncherAction to update the icon based on
      */
-    void mApplicationLaunched(const QString &service);
+    void updateIcon(const LauncherAction &action);
+
+    //! A timer for disabling the progress indicator if the application startup takes a long time
+    QTimer progressIndicatorTimeoutTimer;
+
+    //! Whether an object represented by any launcher button is being launched or not
+    static bool launching;
+
+#ifdef UNIT_TEST
+    friend class Ut_LauncherButton;
+#endif
 };
 
 #endif /* MLAUNCHAPPBUTTON_H */
--- src/home/launcherbuttonmodel.h
+++ src/home/launcherbuttonmodel.h
@@ -21,16 +21,20 @@
 #define LAUNCHERBUTTONMODEL_H_
 
 #include <mbuttonmodel.h>
+#include "launcheraction.h"
 
 class LauncherButtonModel : public MButtonModel
 {
+private:
     Q_OBJECT
     M_MODEL(LauncherButtonModel)
-    M_MODEL_PROPERTY(QString, targetType, TargetType, true, QString())
-    M_MODEL_PROPERTY(QString, target, Target, true, QString())
 
     //! Desktop entry file that launcher button is representing
     M_MODEL_PROPERTY(QString, desktopEntryFile, DesktopEntryFile, true, QString())
+    //! Action for the desktop entry file
+    M_MODEL_PROPERTY(LauncherAction, action, Action, true, LauncherAction())
+    //! Whether to show a progress indicator or not
+    M_MODEL_PROPERTY(bool, showProgressIndicator, ShowProgressIndicator, true, false)
 };
 
 #endif /* LAUNCHERBUTTONMODEL_H_ */
--- src/home/launcherbuttonstyle.h
+++ src/home/launcherbuttonstyle.h
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef LAUNCHERBUTTONSTYLE_H_
+#define LAUNCHERBUTTONSTYLE_H_
+
+#include <mbuttoniconstyle.h>
+
+class LauncherButtonStyle : public MButtonIconStyle
+{
+    Q_OBJECT
+    M_STYLE(LauncherButtonStyle)
+
+    //! The timeout for the progress indicator (in milliseconds)
+    M_STYLE_ATTRIBUTE(int, progressIndicatorTimeout, ProgressIndicatorTimeout)
+
+    //! The number of milliseconds in which the given progress indicator images are animated
+    M_STYLE_ATTRIBUTE(int, progressIndicatorAnimationDuration, ProgressIndicatorAnimationDuration)
+
+    //! The list of IDs of the images to be shown in the progress indicator separated by spaces
+    M_STYLE_ATTRIBUTE(QString, progressIndicatorImageList, ProgressIndicatorImageList)
+};
+
+class LauncherButtonStyleContainer : public MButtonIconStyleContainer
+{
+    M_STYLE_CONTAINER(LauncherButtonStyle)
+};
+
+#endif /* LAUNCHERBUTTONSTYLE_H_ */
--- src/home/launcherbuttonview.cpp
+++ src/home/launcherbuttonview.cpp
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include <QGraphicsAnchorLayout>
+#include "launcherbuttonview.h"
+#include "launcherbutton.h"
+
+LauncherButtonView::LauncherButtonView(LauncherButton *controller) :
+    MButtonIconView(controller),
+    controller(controller)
+{
+    progressIndicatorTimer.setSingleShot(true);
+    progressIndicatorTimeLine.setLoopCount(0);
+    progressIndicatorTimeLine.setCurveShape(QTimeLine::LinearCurve);
+
+    connect(&progressIndicatorTimer, SIGNAL(timeout()), this, SLOT(showProgressIndicator()));
+    connect(&progressIndicatorTimeLine, SIGNAL(frameChanged(int)), this, SLOT(setProgressIndicatorFrame(int)));
+}
+
+LauncherButtonView::~LauncherButtonView()
+{
+}
+
+void LauncherButtonView::setupModel()
+{
+    MButtonIconView::setupModel();
+
+    QList<const char *> modifications;
+    modifications << LauncherButtonModel::ShowProgressIndicator;
+    updateData(modifications);
+}
+
+void LauncherButtonView::applyStyle()
+{
+    MButtonIconView::applyStyle();
+
+    // Set the progress indicator timing properties
+    controller->setProgressIndicatorTimeout(style()->progressIndicatorTimeout());
+    progressIndicatorTimeLine.setDuration(style()->progressIndicatorAnimationDuration());
+    progressIndicatorTimer.setInterval(style()->glowDuration());
+
+    if (!progressIndicatorPixmaps.isEmpty()) {
+        // Release the old progress indicator pixmaps
+        foreach(const QPixmap *pixmap, progressIndicatorPixmaps) {
+            MTheme::releasePixmap(pixmap);
+        }
+
+        progressIndicatorPixmaps.clear();
+    }
+
+    // Load the new progress indicator pixmaps
+    QStringList imageList = style()->progressIndicatorImageList().trimmed().split(QChar(' '));
+    progressIndicatorPixmaps.fill(NULL, imageList.length());
+    for (int i = 0; i < imageList.count(); i++) {
+        progressIndicatorPixmaps.replace(i, MTheme::pixmap(imageList.at(i), style()->iconSize()));
+    }
+    progressIndicatorTimeLine.setFrameRange(0, imageList.count() - 1);
+
+    // Calculate progress indicator rectangle
+    int hPadding = style()->paddingLeft() + style()->paddingRight();
+    int vPadding = style()->paddingTop() + style()->paddingBottom();
+    QRectF contentRect(style()->paddingLeft(), style()->paddingTop(), style()->preferredSize().width() - hPadding, style()->preferredSize().height() - vPadding);
+    progressIndicatorRect.setTopLeft(QPointF(contentRect.center().x() - (style()->iconSize().width() / 2), contentRect.top()));
+    progressIndicatorRect.setSize(style()->iconSize());
+}
+
+void LauncherButtonView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
+{
+    if (progressIndicatorTimeLine.state() == QTimeLine::Running) {
+        // Draw the button icon view first: it messes up with the painter so the state must be saved
+        painter->save();
+        MButtonIconView::drawContents(painter, option);
+        painter->restore();
+
+        // Draw the progress indicator pixmap
+        const QPixmap *pixmap = progressIndicatorPixmaps.at(progressIndicatorTimeLine.currentFrame());
+        if (pixmap != NULL && !pixmap->isNull()) {
+            painter->drawPixmap(progressIndicatorRect, *pixmap, QRectF(pixmap->rect()));
+        }
+    } else {
+        // No progress indicator, so just draw the icon view
+        MButtonIconView::drawContents(painter, option);
+    }
+}
+
+void LauncherButtonView::updateData(const QList<const char *>& modifications)
+{
+    MButtonIconView::updateData(modifications);
+
+    const char *member;
+    foreach(member, modifications) {
+        if (member == LauncherButtonModel::ShowProgressIndicator) {
+            if (model()->showProgressIndicator()) {
+                progressIndicatorTimer.start();
+            } else {
+                hideProgressIndicator();
+            }
+        }
+    }
+}
+
+void LauncherButtonView::setProgressIndicatorFrame(int)
+{
+    update();
+}
+
+void LauncherButtonView::showProgressIndicator()
+{
+    if (progressIndicatorTimer.isActive()) {
+        progressIndicatorTimer.stop();
+    }
+
+    if (progressIndicatorTimeLine.state() != QTimeLine::Running) {
+        progressIndicatorTimeLine.start();
+        update();
+    }
+}
+
+void LauncherButtonView::hideProgressIndicator()
+{
+    if (progressIndicatorTimer.isActive()) {
+        progressIndicatorTimer.stop();
+    }
+
+    if (progressIndicatorTimeLine.state() != QTimeLine::NotRunning) {
+        progressIndicatorTimeLine.stop();
+        update();
+    }
+}
+
+M_REGISTER_VIEW_NEW(LauncherButtonView, LauncherButton)
--- src/home/launcherbuttonview.h
+++ src/home/launcherbuttonview.h
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef LAUNCHERBUTTONVIEW_H_
+#define LAUNCHERBUTTONVIEW_H_
+
+#include <QTimer>
+#include <QTimeLine>
+#include <QRectF>
+#include <mbuttoniconview.h>
+#include "launcherbuttonmodel.h"
+#include "launcherbuttonstyle.h"
+
+class LauncherButton;
+
+/*!
+ * The launcher button view allows a progress indicator to be displayed on top of it.
+ */
+class LauncherButtonView : public MButtonIconView
+{
+    Q_OBJECT
+    M_VIEW(LauncherButtonModel, LauncherButtonStyle)
+
+public:
+    /*!
+     * Constructs a LauncherButtonView.
+     *
+     * \param controller the MButton controller for the view
+     */
+    LauncherButtonView(LauncherButton *controller);
+
+    /*!
+     * Destroys the LauncherButtonView.
+     */
+    virtual ~LauncherButtonView();
+
+protected:
+    //! \reimp
+    virtual void setupModel();
+    virtual void applyStyle();
+    virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
+    //! \reimp_end
+
+protected slots:
+    //! \reimp
+    virtual void updateData(const QList<const char *>& modifications);
+    //! \reimp_end
+
+private slots:
+    //! Shows the progress indicator
+    void showProgressIndicator();
+
+    //! Updates the progress indicator
+    void setProgressIndicatorFrame(int frame);
+
+private:
+    //! Hides the progress indicator
+    void hideProgressIndicator();
+
+    //! The controller for the view
+    LauncherButton *controller;
+
+    //! Pixmaps for the progress indicator
+    QVector<const QPixmap *> progressIndicatorPixmaps;
+
+    //! Timer for bringing forth the progress indicator
+    QTimer progressIndicatorTimer;
+
+    //! Animation timeline for the progress indicator
+    QTimeLine progressIndicatorTimeLine;
+
+    //! Position and size of the progress indicator
+    QRectF progressIndicatorRect;
+
+#ifdef UNIT_TEST
+    friend class Ut_LauncherButtonView;
+#endif
+};
+
+#endif /* LAUNCHERBUTTONVIEW_H_ */
--- src/home/launcherpageview.cpp
+++ src/home/launcherpageview.cpp
@@ -23,6 +23,7 @@
 #include "launcherbutton.h"
 #include <MLayout>
 #include <MFlowLayoutPolicy>
+#include <QSet>
 
 LauncherPageView::LauncherPageView(LauncherPage *controller) :
     MWidgetView(controller),
@@ -35,6 +36,10 @@
 
 LauncherPageView::~LauncherPageView()
 {
+    // remove buttons from layout to avoid multi deletion (buttons are in model as QSharedPointer's)
+    foreach (QSharedPointer<LauncherButton> button, model()->launcherButtons()) {
+        removeButtonFromLayout(button.data());
+    }
 }
 
 void LauncherPageView::updateData(const QList<const char *>& modifications)
@@ -43,45 +48,46 @@
     const char *member;
     foreach(member, modifications) {
         if (member == LauncherPageModel::LauncherButtons) {
-            updateLayoutFromButtonList();
+            updateLayoutFromModel();
         }
     }
 }
 
-void LauncherPageView::updateLayoutFromButtonList()
+void LauncherPageView::updateLayoutFromModel()
 {
-    QList<QSharedPointer<LauncherButton> > buttons = model()->launcherButtons();
+    // Set of buttons in layout
+    QSet<LauncherButton *> layoutButtons;
+    for (int i = 0; i < layout->count(); i++) {
+        layoutButtons.insert(static_cast<LauncherButton *>(layout->itemAt(i)));
+    }
 
-    // Add new buttons (buttons that are found from button list but not from layout)
-    foreach(QSharedPointer<LauncherButton> listButton, buttons) {
-        bool contains = false;
-        for (int i = 0; i < layout->count(); i++) {
-            LauncherButton *layoutButton = dynamic_cast<LauncherButton *> (layout->itemAt(i));
-            if (listButton.data() == layoutButton) {
-                contains = true;
-                break;
-            }
-        }
+    // List of buttons in model (list needed to assure the order of buttons)
+    QList<LauncherButton *> modelButtonsList;
+    foreach(QSharedPointer<LauncherButton> modelButton, model()->launcherButtons()) {
+        modelButtonsList.append(modelButton.data());
+    }
 
-        if (!contains) {
-            policy->addItem(listButton.data());
-        }
+    // Set of buttons in model
+    QSet<LauncherButton *> modelButtonsSet(modelButtonsList.toSet());
+
+    // Remove from layout the buttons that doesn't exists any more in model
+    QSet<LauncherButton *> deletedButtons = layoutButtons - modelButtonsSet;
+    foreach (LauncherButton *deletedButton, deletedButtons) {
+        removeButtonFromLayout(deletedButton);
     }
 
-    // Remove non-existent pages (pages that are in layout but not in page list)
-    for (int i = 0; i < layout->count(); i++) {
-        LauncherButton *layoutButton = dynamic_cast<LauncherButton *> (layout->itemAt(i));
-        bool contains = false;
-        foreach(QSharedPointer<LauncherButton> listButton, buttons) {
-            if (listButton.data() == layoutButton) {
-                contains = true;
-                break;
-            }
-        }
+    // Get buttons that are new in model to a map (with model list index as a key) for sorting
+    QSet<LauncherButton *> newButtons = modelButtonsSet - layoutButtons;
+    QMap<int, LauncherButton *> newButtonsSorted;
+    foreach (LauncherButton *addedButton, newButtons) {
+        newButtonsSorted.insert(modelButtonsList.indexOf(addedButton), addedButton);
+    }
 
-        if (!contains) {
-            layout->removeItem(layoutButton);
-        }
+    // Add new buttons to layout in sorted order
+    QMapIterator<int, LauncherButton *> iter(newButtonsSorted);
+    while (iter.hasNext()) {
+        iter.next();
+        policy->insertItem(iter.key(), iter.value());
     }
 }
 
@@ -94,4 +100,11 @@
     updateData(modifications);
 }
 
+void LauncherPageView::removeButtonFromLayout(LauncherButton *button)
+{
+    layout->removeItem(button);
+    // set parent to NULL to avoid double deletion as items are as QSharedPointers in model
+    button->setParentItem(0);
+}
+
 M_REGISTER_VIEW_NEW(LauncherPageView, LauncherPage)
--- src/home/launcherpageview.h
+++ src/home/launcherpageview.h
@@ -65,9 +65,19 @@
      *
      * Adds new buttons and removes non-exitent.
      */
-    void updateLayoutFromButtonList();
+    void updateLayoutFromModel();
 
-    //! A layout for the buttons 
+    /*!
+     * Removes a button from layout and sets its parent to null.
+     *
+     * View or layout are not responsible for deleting the button after this.
+     *
+     * \param button Button to be removed.
+     */
+    void removeButtonFromLayout(LauncherButton *button);
+
+
+    //! A layout for the buttons
     MLayout *layout;
     //! A flow layout policy for the widgets
     MFlowLayoutPolicy *policy;
--- src/home/launcherview.cpp
+++ src/home/launcherview.cpp
@@ -50,10 +50,15 @@
     pagedViewport->setPanDirection(Qt::Horizontal);
 
     connect(controller, SIGNAL(panningRequested(uint)), this, SLOT(panToPage(uint)));
+    connect(controller, SIGNAL(focusToFirstPageRequested()), this, SLOT(focusFirstPage()));
 }
 
 LauncherView::~LauncherView()
 {
+    // remove pages from layout to avoid multi deletion (pages are in model as QSharedPointer's)
+    foreach (QSharedPointer<LauncherPage> page, model()->launcherPages()) {
+        removePageFromLayout(page.data());
+    }
 }
 
 void LauncherView::updateData(const QList<const char *>& modifications)
@@ -62,47 +67,47 @@
     const char *member;
     foreach(member, modifications) {
         if (member == LauncherModel::LauncherPages) {
-            updateLayoutFromPageList();
+            updateLayoutFromModel();
 
             pagedViewport->updatePageCount(model()->launcherPages().count());
         }
     }
 }
 
-void LauncherView::updateLayoutFromPageList()
+void LauncherView::updateLayoutFromModel()
 {
-    QList<QSharedPointer<LauncherPage> > pages = model()->launcherPages();
+    // Set of pages in layout
+    QSet<LauncherPage *> layoutPages;
+    for (int i = 0; i < layout->count(); i++) {
+        layoutPages.insert(static_cast<LauncherPage *>(layout->itemAt(i)));
+    }
 
-    // Add new pages (pages that are found from page list but not from layout)
-    foreach(QSharedPointer<LauncherPage> listPage, pages) {
-        bool contains = false;
-        for (int i = 0; i < layout->count(); i++) {
-            LauncherPage *layoutPage = dynamic_cast<LauncherPage *> (layout->itemAt(i));
-            if (listPage.data() == layoutPage) {
-                contains = true;
-                break;
-            }
-        }
+    // List of pages in model (list needed for the order of pages)
+    QList<LauncherPage *> modelPagesList;
+    foreach(QSharedPointer<LauncherPage> modelPage, model()->launcherPages()) {
+        modelPagesList.append(modelPage.data());
+    }
+    // Set of pages in model
+    QSet<LauncherPage *> modelPagesSet(modelPagesList.toSet());
 
-        if (!contains) {
-            policy->addItem(listPage.data());
-        }
+    // Remove from layout the pages that doesn't exists any more in model
+    QSet<LauncherPage *> deletedPages = layoutPages - modelPagesSet;
+    foreach (LauncherPage *deletedPage, deletedPages) {
+        removePageFromLayout(deletedPage);
     }
 
-    // Remove pages that doesn't exist anymore
-    for (int i = 0; i < layout->count(); i++) {
-        bool contains = false;
-        LauncherPage *layoutPage = dynamic_cast<LauncherPage *> (layout->itemAt(i));
-        foreach(QSharedPointer<LauncherPage> listPage, pages) {
-            if (listPage.data() == layoutPage) {
-                contains = true;
-                break;
-            }
-        }
+    // Get pages that are new in model to a map (with model list index as a key) for sorting
+    QSet<LauncherPage *> newPages = modelPagesSet - layoutPages;
+    QMap<int, LauncherPage *> newPagesSorted;
+    foreach (LauncherPage *addedPage, newPages) {
+        newPagesSorted.insert(modelPagesList.indexOf(addedPage), addedPage);
+    }
 
-        if (!contains) {
-            layout->removeItem(layoutPage);
-        }
+    // Add new pages to layout in sorted order
+    QMapIterator<int, LauncherPage *> iter(newPagesSorted);
+    while (iter.hasNext()) {
+        iter.next();
+        policy->insertItem(iter.key(), iter.value());
     }
 }
 
@@ -111,4 +116,16 @@
     pagedViewport->panToPage(page);
 }
 
+void LauncherView::focusFirstPage()
+{
+    pagedViewport->focusFirstPage();
+}
+
+void LauncherView::removePageFromLayout(LauncherPage *page)
+{
+    layout->removeItem(page);
+    // set parent to NULL to avoid double deletion as items are as QSharedPointers in model
+    page->setParentItem(0);
+}
+
 M_REGISTER_VIEW_NEW(LauncherView, Launcher)
--- src/home/launcherview.h
+++ src/home/launcherview.h
@@ -72,6 +72,11 @@
      */
     void panToPage(uint page);
 
+    /*!
+     * Focus launcher to first page
+     */
+    void focusFirstPage();
+
 private:
 
     /*!
@@ -79,7 +84,16 @@
      *
      * Adds new pages and removes non-exitent.
      */
-    void updateLayoutFromPageList();
+    void updateLayoutFromModel();
+
+    /*!
+     * Removes a page from layout and sets its parent to null.
+     *
+     * View or layout are not responsible for deleting the page after this.
+     *
+     * \param page Page to be removed.
+     */
+    void removePageFromLayout(LauncherPage *page);
 
     //! A layout for the widgets
     MLayout *layout;
--- src/home/pagedpanning.cpp
+++ src/home/pagedpanning.cpp
@@ -30,7 +30,6 @@
                                               dragThreshold_(0.5),
                                               pageSnapSpringK_(0.7),
                                               pageSnapFriction_(0.7),
-                                              previousPointerPressed(false),
                                               previousPosition(0),
                                               targetPage(0),
                                               pageWidth(0)
@@ -38,6 +37,7 @@
     // Whenever panning stops for reason or the other, make sure the
     // view ends up on top of a page.
     connect(this, SIGNAL(panningStopped()), this, SLOT(panToCurrentPage()));
+    setPanDirection(Qt::Horizontal);
 }
 
 PagedPanning::~PagedPanning()
@@ -58,14 +58,14 @@
 
     qreal rangeStart = range().left();
     qreal rangeEnd = range().right();
-    qreal force;
+    qreal force = 0.0;
 
     pageWidth = (rangeEnd - rangeStart) / qMax(1, pageCount_-1);
 
-    // Damping
     if (position >= rangeStart && position <= rangeEnd) {
         // Inside range
         if (pointerPressed) {
+            // Drag friction
             force = -friction() * velocity;
         } else if (snapMode) {
             force = -pageSnapFriction_ * velocity;
@@ -77,79 +77,40 @@
         force = -borderFriction() * velocity;
     }
 
-    if (pointerPressed == true && previousPointerPressed == false) {
-        initialPage = currentPage;
-    }
-
-    if (pointerPressed) {
-        // Pointer spring
-        force += -pointerSpringK() * pointerDifference;
-        // Stop the automatic panning when the pointer comes down
-        snapMode = false;
-
-        /* Target the next page if the view has been dragged over the
-           dragThreshold. */
-        qreal distanceToInitialPage = position - initialPage*pageWidth;
-        int draggedPages;
-
-        if (distanceToInitialPage > 0) {
-            draggedPages = (int)(distanceToInitialPage/pageWidth + (1.0-dragThreshold_));
-        } else {
-            draggedPages = (int)(distanceToInitialPage/pageWidth - (1.0-dragThreshold_));
-        }
-
-        targetPage = qBound(0, initialPage + draggedPages, pageCount_-1);
-
-        if( currentPage != targetPage) {
-            emit pageChanged(targetPage);
-            currentPage = targetPage;
-        }
-    }
-
     if (previousRange != range()) {
-        /*
-           Pan the viewport to the correct page
-           in case the underlying widget's size and
-           therefore the page width has changed.
-         */
-        snapMode = true;
-        targetPage = currentPage;
+
         previousRange = range();
-    }
 
-    // Check if pointer was just lifted
-    if (pointerPressed == false && previousPointerPressed == true) {
-        // The number of pages to slide
-        qreal slidePages = slideDistance(velocity, slidingFriction())/pageWidth;
-        // Remove half a page; only slide over the center of a page if really going
-        // to the next one
-        slidePages -= slidePages > 0 ? 0.5 : -0.5;
-
-        targetPage = currentPage + (int)slidePages;
-
-        /* Pan to the next page if a strong enough flick was performed. */
-        if ( targetPage == initialPage
-             && std::fabs(velocity) > velocityThreshold_ ) {
-            targetPage += velocity > 0 ? 1 : -1;
+        if( pageWidth != 0 && previousPageWidth != pageWidth ) {
+            /* A change in the page width means the orientation has
+               changed - move the view to the correct position immediately */
+            position = pageWidth * currentPage;
+            force = 0;
+            velocity = 0;
+            acceleration = 0;
+        } else {
+            /* If the page width has remained the same, the number of
+               pages must have changed */
             snapMode = true;
         }
 
-        if (slideLimit_ > 0)
-            targetPage = qBound(initialPage-slideLimit_,
-                                targetPage,
-                                initialPage+slideLimit_);
-
+        targetPage = currentPage;
     }
 
-    /* The target page must be inside the panning range, this is to make sure
-       that we do not go out side the range */
-    targetPage = qBound(0, targetPage, pageCount_-1);
+    if (pointerPressed) {
+        // Pointer spring
+        force += -pointerSpringK() * pointerDifference;
+    } else {
+        /* The target page must be inside the panning range, this is to make sure
+           that we do not go out side the range */
+        targetPage = qBound(0, targetPage, pageCount_-1);
 
-    if ( !pointerPressed ) {
         int nearestPage = 0;
 
         if (pageWidth > 0) {
             nearestPage = (int)((position / (qreal)pageWidth) + 0.5);
+            // nearestPage is the nearest page in the valid range
+            nearestPage = qBound(0, nearestPage, pageCount_-1);
         }
 
         // Cap the nearestPage at targetPage, in case
@@ -181,7 +142,7 @@
 
             qreal closeEnough = position - (pageWidth * targetPage);
 
-            if (abs(closeEnough) < 1 && abs(force) < 1) {
+            if (abs(closeEnough) < 2 && abs(force) < 2) {
                 // Setting these to zero should stop the integration process
                 force = 0;
                 velocity = 0;
@@ -199,14 +160,16 @@
     position      += velocity;
     pointerDifference += velocity;
 
-    previousPointerPressed = pointerPressed;
     previousPosition = position;
+    previousPageWidth = pageWidth;
 }
 
 void PagedPanning::setPageCount(int newPageCount)
 {
     pageCount_ = qMax(1, newPageCount);
-    panToPage(qMin(newPageCount - 1, currentPage));
+    initialPage = currentPage;
+    targetPage = qMin(newPageCount - 1, currentPage);
+    snapMode = true;
 }
 
 int PagedPanning::pageCount() const
@@ -280,9 +243,81 @@
        log(finalVelocity/initialVelocity) = t*log((1-friction))
                                         t = log(finalVelocity/initialVelocity)/log(1-friction)
      */
-    qreal b = 1.0-friction;
+    if (initialVelocity == 0)
+        return 0;
+
+    qreal b = 1.0-qMin((qreal)1.0, friction);
     qreal logb = std::log(b);
     qreal t = std::log(SLIDE_FINAL_VELOCITY / std::fabs(initialVelocity)) / logb;
 
     return initialVelocity * (std::pow(b, t)-1.0) / logb;
 }
+
+void PagedPanning::pointerPress(const QPointF &pos)
+{
+    MPhysics2DPanning::pointerPress(pos);
+
+    pageWidth = (range().right() - range().left()) / qMax(1, pageCount_-1);
+    //currentPage = position().x()/pageWidth;
+    initialPage = currentPage;
+
+    // Stop the automatic panning when the pointer comes down
+    snapMode = false;
+}
+
+void PagedPanning::pointerMove(const QPointF &pos)
+{
+    MPhysics2DPanning::pointerMove(pos);
+
+    /* Target the next page if the view has been dragged over the
+       dragThreshold. */
+    qreal distanceToInitialPage = position().x() - initialPage*pageWidth;
+    int draggedPages;
+
+    if (distanceToInitialPage > 0) {
+        draggedPages = (int)(distanceToInitialPage/pageWidth + (1.0-dragThreshold_));
+    } else {
+        draggedPages = (int)(distanceToInitialPage/pageWidth - (1.0-dragThreshold_));
+    }
+
+    targetPage = qBound(0, initialPage + draggedPages, pageCount_-1);
+
+    if( currentPage != targetPage) {
+        emit pageChanged(targetPage);
+        currentPage = targetPage;
+    }
+}
+
+void PagedPanning::pointerRelease()
+{
+    MPhysics2DPanning::pointerRelease();
+
+    // The number of pages to slide
+    qreal slidePages = slideDistance(velocity().x(), slidingFriction())/pageWidth;
+    // Remove half a page; only slide over the center of a page if really going
+    // to the next one
+    slidePages -= slidePages > 0 ? 0.5 : -0.5;
+
+    targetPage = currentPage + (int)slidePages;
+
+    /* Pan to the next page if a strong enough flick was performed. */
+    if ( targetPage == initialPage
+            && std::fabs(velocity().x()) > velocityThreshold_ ) {
+        targetPage += velocity().x() > 0 ? 1 : -1;
+        snapMode = true;
+    }
+
+    if (slideLimit_ > 0)
+        targetPage = qBound(initialPage-slideLimit_,
+                            targetPage,
+                            initialPage+slideLimit_);
+}
+
+void PagedPanning::setFirstPagePosition()
+{
+    //TODO: add support for setting position to the right-most page
+    // when using right-to-left layout
+    currentPage = 0;
+    targetPage = 0;
+    setPosition(QPointF(0.0, 0.0));
+}
--- src/home/pagedpanning.h
+++ src/home/pagedpanning.h
@@ -86,6 +86,10 @@
      */
     void setPageSnapFriction(qreal value);
 
+    /*!
+     * Sets page position to the first page
+     */
+    void setFirstPagePosition();
 
 protected:
 
@@ -97,6 +101,13 @@
                                 qreal &pointerDifference,
                                 bool pointerPressed
                                 );
+
+    virtual void pointerPress(const QPointF &pos);
+
+    virtual void pointerMove(const QPointF &pos);
+
+    virtual void pointerRelease();
+
     //! \reimp_end
 
 signals:
@@ -143,9 +154,6 @@
     //! Page snapping spring damping friction factor
     qreal pageSnapFriction_;
 
-    //! The pointer press state during the previous integration step
-    bool previousPointerPressed;
-
     //! The view position during the previous integration step
     qreal previousPosition;
 
@@ -158,6 +166,9 @@
     //! Current page width
     qreal pageWidth;
 
+    //! Page width during the previous integration step
+    qreal previousPageWidth;
+
     /*! Calculate the sliding distance with the given
      *  initial velocity and friction factor.
      */
--- src/home/pagedviewport.cpp
+++ src/home/pagedviewport.cpp
@@ -54,6 +54,11 @@
     pagedPanning->panToPage(page);
 }
 
+void PagedViewport::focusFirstPage()
+{
+    pagedPanning->setFirstPagePosition();
+}
+
 void PagedViewport::updatePageCount(int pages)
 {
     pages_ = pages;
--- src/home/pagedviewport.h
+++ src/home/pagedviewport.h
@@ -98,6 +98,11 @@
      */
     void panToPage(uint page);
 
+    /*!
+     * Moves the viewport to the first page
+     */
+    void focusFirstPage();
+
 private:
     //! Our custom phyics implementation
     PagedPanning* pagedPanning;
--- src/home/switcher.cpp
+++ src/home/switcher.cpp
@@ -16,7 +16,6 @@
 ** of this file.
 **
 ****************************************************************************/
-
 #include <QX11Info>
 #include <QApplication>
 #include <MLayout>
@@ -25,82 +24,42 @@
 #include "switcher.h"
 #include "switcherbutton.h"
 #include "windowinfo.h"
+#include "mainwindow.h"
+#include "x11wrapper.h"
+
+// The time to wait until updating the model when a new application is started
+#define UPDATE_DELAY_MS 700
 
 Switcher::Switcher(MWidget *parent) :
-    MWidgetController(new SwitcherModel, parent)
+    MWidgetController(new SwitcherModel, parent), windowListUpdated(false)
 {
     // Connect to the windowListUpdated signal of the HomeApplication to get information about window list changes
-    connect(qApp, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), this, SLOT(windowListUpdated(const QList<WindowInfo> &)));
+    connect(qApp, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), this, SLOT(updateWindowList(const QList<WindowInfo> &)));
     connect(qApp, SIGNAL(windowTitleChanged(Window, QString)), this, SLOT(changeWindowTitle(Window, QString)));
 
     // Get the X11 Atoms for closing and activating a window
-    closeWindowAtom  = XInternAtom(QX11Info::display(), "_NET_CLOSE_WINDOW",  False);
-    activeWindowAtom = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", False);
+    closeWindowAtom  = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLOSE_WINDOW",  False);
+    activeWindowAtom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", False);
 }
 
 Switcher::~Switcher()
 {
 }
 
-void Switcher::windowListUpdated(const QList<WindowInfo> &windowList)
+void Switcher::updateWindowList(const QList<WindowInfo> &newList)
 {
-    QList< QSharedPointer<SwitcherButton> > oldButtons(model()->buttons());
-
-    // List of existing buttons for which a window still exists
-    QList< QSharedPointer<SwitcherButton> > currentButtons;
-
-    // List of newly created buttons
-    QList< QSharedPointer<SwitcherButton> > newButtons;
-
-    // List to be set as the new list in the model
-    QList< QSharedPointer<SwitcherButton> > nextButtons;
-
-    // The new mapping of known windows to the buttons
-    QMap<Window, SwitcherButton *> newWindowMap;
-
-    // Go through the windows and create new buttons for new windows
-    foreach(WindowInfo wi, windowList) {
-        if (windowMap.contains(wi.window())) {
-            SwitcherButton *b = windowMap[wi.window()];
+    int previousWindowCount = windowList.count();
+    windowList = newList;
 
-            // Button already exists - set title and priority (as they may have changed)
-            b->setText(wi.title());
-            b->setWindowPriority(wi.windowPriority());
+    windowListUpdated = true;
 
-            newWindowMap[wi.window()] = b;
-        } else {
-            QSharedPointer<SwitcherButton> b(new SwitcherButton(wi.title(), NULL, wi.window(), wi.windowPriority()));
-            connect(b.data(), SIGNAL(windowToFront(Window)), this, SLOT(windowToFront(Window)));
-            connect(b.data(), SIGNAL(closeWindow(Window)), this, SLOT(closeWindow(Window)));
-
-            // Put the new high priority buttons straight to the top
-            if (wi.windowPriority() == WindowInfo::Call) {
-                nextButtons.append(b);
-            } else {
-                newButtons.append(b);
-            }
-
-            newWindowMap[wi.window()] = b.data();
-        }
+    // If no new windows have appeared, i.e. an application is not currently
+    // starting, update the buttons immediately - otherwise, wait a bit
+    if( previousWindowCount >= newList.count() ) {
+        updateButtons();
+    } else {
+        QTimer::singleShot(UPDATE_DELAY_MS, this, SLOT(updateButtons()));
     }
-
-    foreach(QSharedPointer<SwitcherButton> b, oldButtons) {
-        // Keep only the buttons for which a window still exists
-        if (newWindowMap.contains(b.data()->xWindow())) {
-            if (b.data()->windowPriority() == WindowInfo::Call) {
-                currentButtons.prepend(b);
-            } else {
-                currentButtons.append(b);
-            }
-        }
-    }
-
-    windowMap = newWindowMap;
-    nextButtons.append(currentButtons);
-    nextButtons.append(newButtons);
-
-    // Take the new set of buttons into use
-    model()->setButtons(nextButtons);
 }
 
 void Switcher::windowToFront(Window window)
@@ -120,9 +79,9 @@
     ev.xclient.data.l[1]    = CurrentTime;
     ev.xclient.data.l[2]    = 0;
 
-    XSendEvent(display,
-               rootWin, False,
-               SubstructureRedirectMask, &ev);
+    X11Wrapper::XSendEvent(display,
+                           rootWin, False,
+                           StructureNotifyMask, &ev);
 }
 
 void Switcher::closeWindow(Window window)
@@ -141,17 +100,9 @@
     ev.xclient.data.l[0]    = CurrentTime;
     ev.xclient.data.l[1]    = rootWin;
 
-    XSendEvent(display,
-               rootWin, False,
-               SubstructureRedirectMask, &ev);
-}
-
-void Switcher::viewportSizePosChanged(const QSizeF &, const QRectF &, const QPointF &)
-{
-    foreach(QSharedPointer<SwitcherButton> b, model()->buttons()) {
-        // Update the icon geometry of each button when the viewport is panned
-        b->updateIconGeometry();
-    }
+    X11Wrapper::XSendEvent(display,
+                           rootWin, False,
+                           SubstructureRedirectMask, &ev);
 }
 
 void Switcher::changeWindowTitle(Window window,  const QString &title)
@@ -161,3 +112,64 @@
         windowMap.value(window)->update();
     }
 }
+
+
+void Switcher::updateButtons()
+{
+    if( windowListUpdated ) {
+
+        windowListUpdated = false;
+
+        QList< QSharedPointer<SwitcherButton> > oldButtons(model()->buttons());
+
+        // List of existing buttons for which a window still exists
+        QList< QSharedPointer<SwitcherButton> > currentButtons;
+
+        // List of newly created buttons
+        QList< QSharedPointer<SwitcherButton> > newButtons;
+
+        // List to be set as the new list in the model
+        QList< QSharedPointer<SwitcherButton> > nextButtons;
+
+        // The new mapping of known windows to the buttons
+        QMap<Window, SwitcherButton *> newWindowMap;
+
+        // Go through the windows and create new buttons for new windows
+        foreach(WindowInfo wi, windowList) {
+            if (windowMap.contains(wi.window())) {
+                SwitcherButton *b = windowMap[wi.window()];
+
+                // Button already exists - set title (as it may have changed)
+                b->setText(wi.title());
+
+                newWindowMap[wi.window()] = b;
+            } else {
+                QSharedPointer<SwitcherButton> b(new SwitcherButton(wi.title(), NULL, wi.window()));
+                connect(b.data(), SIGNAL(windowToFront(Window)), this, SLOT(windowToFront(Window)));
+                connect(b.data(), SIGNAL(closeWindow(Window)), this, SLOT(closeWindow(Window)));
+
+                newButtons.append(b);
+
+                newWindowMap[wi.window()] = b.data();
+            }
+        }
+
+        foreach(QSharedPointer<SwitcherButton> b, oldButtons) {
+            // Keep only the buttons for which a window still exists
+            if (newWindowMap.contains(b.data()->xWindow())) {
+                currentButtons.append(b);
+            }
+        }
+
+        windowMap = newWindowMap;
+        nextButtons.append(currentButtons);
+        nextButtons.append(newButtons);
+
+        // Take the new set of buttons into use
+        model()->setButtons(nextButtons);
+    }
+}
+
+void Switcher::scheduleUpdate() {
+    QTimer::singleShot(UPDATE_DELAY_MS, this, SLOT(updateButtons()));
+}
--- src/home/switcher.h
+++ src/home/switcher.h
@@ -51,7 +51,7 @@
     /*!
      * \brief A slot for notifying that the window list has been updated
      */
-    void windowListUpdated(const QList<WindowInfo> &windowList);
+    void updateWindowList(const QList<WindowInfo> &newList);
 
     /*!
      * \brief A slot for notifying that a window should be brought to front
@@ -64,16 +64,22 @@
     void closeWindow(Window window);
 
     /*!
-     * \brief A slot for getting information about changes in the viewport in which the switcher resides
+     * \brief A slot for changing a window title of a switcher button
      */
-    void viewportSizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos);
+    void changeWindowTitle(Window window,  const QString &title);
 
     /*!
-     * \brief A slot for changing a window title of a switcher button
+     * \brief Updates the buttons in the model based on the new window list
      */
-    void changeWindowTitle(Window window,  const QString &title);
+    void updateButtons();
 
 private:
+
+    /*!
+     * \brief Starts a timer which eventually calls updateButtons
+     */
+    void scheduleUpdate();
+
     //! X11 Atom for the close window message type
     Atom closeWindowAtom;
 
@@ -82,6 +88,16 @@
 
     //! A mapping from known X Window ids to SwitcherButtons
     QMap<Window, SwitcherButton *> windowMap;
+
+    //! The latest window list supplied through updateWindowList
+    QList<WindowInfo> windowList;
+
+    //! True if the window list has been updated since the last updateButtons
+    bool windowListUpdated;
+
+#ifdef UNIT_TEST
+    friend class Ut_Switcher;
+#endif
 };
 
 #endif // SWITCHER_H
--- src/home/switcherbutton.cpp
+++ src/home/switcherbutton.cpp
@@ -25,26 +25,23 @@
 #include "x11wrapper.h"
 #include <QX11Info>
 
-Atom SwitcherButton::iconGeometryAtom = 0;
+Atom SwitcherButton::visibleAtom = 0;
 
-SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window, WindowInfo::WindowPriority windowPriority) :
-    MButton(title, parent, new SwitcherButtonModel),
-    priority(windowPriority)
+SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window) :
+    MButton(title, parent, new SwitcherButtonModel)
 {
     // Configure timers
     windowCloseTimer.setSingleShot(true);
     connect(&windowCloseTimer, SIGNAL(timeout()), this, SLOT(resetState()));
 
-    if (iconGeometryAtom == 0) {
+    if (visibleAtom == 0) {
         // Get the icon geometry X11 Atom if it doesn't exist yet
-        iconGeometryAtom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_WM_ICON_GEOMETRY", False);
+        visibleAtom = X11Wrapper::XInternAtom(QX11Info::display(), "_MEEGOTOUCH_VISIBLE_IN_SWITCHER", False);
     }
 
     // Update the window title and pixmap
     model()->setXWindow(window);
 
-    connect(MainWindow::instance(), SIGNAL(orientationChangeFinished(const M::Orientation &)), this, SLOT(updateIconGeometry()));
-
     connect(this, SIGNAL(clicked()), this, SLOT(switchToWindow()));
 }
 
@@ -57,16 +54,6 @@
     return model()->xWindow();
 }
 
-WindowInfo::WindowPriority SwitcherButton::windowPriority() const
-{
-    return priority;
-}
-
-void SwitcherButton::setWindowPriority(WindowInfo::WindowPriority windowPriority)
-{
-    priority = windowPriority;
-}
-
 void SwitcherButton::switchToWindow()
 {
     emit windowToFront(model()->xWindow());
@@ -85,31 +72,33 @@
     QGraphicsItem::prepareGeometryChange();
 }
 
-void SwitcherButton::setGeometry(const QRectF &rect)
+void SwitcherButton::resetState()
 {
-    MButton::setGeometry(rect);
+    setVisible(true);
+    prepareGeometryChange();
+}
 
-    // When the switcher button's geometry is changed update the icon geometry
-    updateIconGeometry();
+void SwitcherButton::enterDisplayEvent()
+{
+    setVisibleInSwitcherProperty(true);
 }
 
-void SwitcherButton::resetState()
+void SwitcherButton::exitDisplayEvent()
 {
-    setVisible(true);
-    prepareGeometryChange();
+    setVisibleInSwitcherProperty(false);
 }
 
-void SwitcherButton::updateIconGeometry()
+void SwitcherButton::setVisibleInSwitcherProperty(bool set)
 {
-    // Get the position of the Switcher Button in scene coordinates
-    QRectF iconPosition = boundingRect();
-    iconPosition.moveTo(mapToScene(0, 0));
-
-    // Replace the old X icon geometry property for the window with iconGeometry, which consists of 4 unsigned ints (32 bits)
-    unsigned int iconGeometry[4];
-    iconGeometry[0] = iconPosition.x();
-    iconGeometry[1] = iconPosition.y();
-    iconGeometry[2] = iconPosition.width();
-    iconGeometry[3] = iconPosition.height();
-    X11Wrapper::XChangeProperty(QX11Info::display(), xWindow(), iconGeometryAtom, XA_CARDINAL, sizeof(unsigned int) * 8, PropModeReplace, (unsigned char *)&iconGeometry, 4);
+    Display *dpy = QX11Info::display();
+    if (dpy) {
+        if (set) {
+            unsigned char data = 1;
+            X11Wrapper::XChangeProperty(dpy, xWindow(), visibleAtom, XA_CARDINAL, 8, PropModeReplace, &data, 1);
+        } else {
+            unsigned char data = 0;
+            X11Wrapper::XChangeProperty(dpy, xWindow(), visibleAtom, XA_CARDINAL, 8, PropModeReplace, &data, 1);
+        }
+    }
 }
+
--- src/home/switcherbutton.h
+++ src/home/switcherbutton.h
@@ -41,9 +41,8 @@
      * \param title the Title of the window represented by this button
      * \param parent parent MWidget
      * \param window the X Window represented by this button
-     * \param priority the priority of the X Window represented by this button
      */
-    SwitcherButton(const QString &title, MWidget *parent = NULL, Window window = 0, WindowInfo::WindowPriority windowPriority = WindowInfo::Normal);
+    SwitcherButton(const QString &title, MWidget *parent = NULL, Window window = 0);
 
     /*!
      * Destroys the SwitcherButton.
@@ -55,24 +54,16 @@
      */
     Window xWindow();
 
-    /*!
-     * Gets the priority of the X Window represented by this button
-     */
-    WindowInfo::WindowPriority windowPriority() const;
-
-    /*!
-     * Sets the priority of the X Window represented by this button
-     */
-    void setWindowPriority(WindowInfo::WindowPriority windowPriority);
-
     /*! \reimp
      *
      * Reimplemented here as public because it's protected in the base class so the view cannot access it.
      */
     virtual void prepareGeometryChange();
-    virtual void setGeometry(const QRectF &rect);
     //! \reimp_end
 
+    //! Sets/unsets _MEEGO_VISIBLE_IN_SWITCHER property to the window.
+    void setVisibleInSwitcherProperty(bool set);
+
 signals:
     /*!
      * \brief A signal for notifying that a window should be brought to front
@@ -100,20 +91,27 @@
      */
     void resetState();
 
-    /*!
-     * \brief Updates the _NET_WM_ICON_GEOMETRY X property for the Window
+protected:
+
+    /*! \reimp
+     *
+     * Reimplemented to update _MEEGO_VISIBLE_IN_SWITCHER property
+     */
+    virtual void enterDisplayEvent();
+
+    /*! \reimp
+     *
+     * Reimplemented to update _MEEGO_VISIBLE_IN_SWITCHER property
      */
-    void updateIconGeometry();
+    virtual void exitDisplayEvent();
 
 private:
+
     //! A timer to check if the window is closed when switcher button is dragged outside switcher before timer expires
     QTimer windowCloseTimer;
 
-    //! X11 Atom for the icon geometry
-    static Atom iconGeometryAtom;
-
-    //! Window priority
-    WindowInfo::WindowPriority priority;
+    //! X11 Atom for window being visible in the switcher
+    static Atom visibleAtom;
 };
 
 #endif // SWITCHERBUTTON_H
--- src/home/switcherbuttonstyle.h
+++ src/home/switcherbuttonstyle.h
@@ -34,14 +34,11 @@
     Q_OBJECT
     M_STYLE(SwitcherButtonStyle)
 
-    //! The opacity of the title
-    M_STYLE_ATTRIBUTE(qreal, textOpacity, TextOpacity)
+    //! Close button vertical offset relative to top-right corner of switcher button
+    M_STYLE_ATTRIBUTE(qreal, closeButtonVOffset, CloseButtonVOffset)
 
-    //! The position of the icon relative to the top-left corner of the button
-    M_STYLE_ATTRIBUTE(QPointF, iconPosition, IconPosition)
-
-    //! The close button
-    M_STYLE_ATTRIBUTE(qreal, closeButtonVerticalPosition, CloseButtonVerticalPosition)
+    //! Close button horizontal offset relative to top-right corner of switcher button
+    M_STYLE_ATTRIBUTE(qreal, closeButtonHOffset, CloseButtonHOffset)
 
     //! The close button icon
     M_STYLE_ATTRIBUTE(QString, closeIcon, CloseIcon)
--- src/home/switcherbuttonview.cpp
+++ src/home/switcherbuttonview.cpp
@@ -18,23 +18,28 @@
 ****************************************************************************/
 
 #include <cmath>
-#include <QTimer>
 #include <QGraphicsSceneMouseEvent>
 #include "mainwindow.h"
-#include <QApplication>
+#include <MApplication>
 #include <QX11Info>
 #include <QPainter>
 #include <MScalableImage>
 #include <MCancelEvent>
 #include <MSceneManager>
+#include <MLayout>
+#include <MLabel>
+#include <MLinearLayoutPolicy>
 #include "switcherbuttonview.h"
 #include "switcherbutton.h"
+#include "x11wrapper.h"
 
 #ifdef Q_WS_X11
 bool SwitcherButtonView::badMatchOccurred = false;
 #endif
 
 const int SwitcherButtonView::NAVIGATION_BAR_HEIGHT = 100;
+const int SwitcherButtonView::ICON_GEOMETRY_UPDATE_INTERVAL = 200;
+Atom SwitcherButtonView::iconGeometryAtom = 0;
 
 SwitcherButtonView::SwitcherButtonView(SwitcherButton *button) :
     MButtonView(button),
@@ -49,14 +54,36 @@
     // Show interest in X pixmap change signals
     connect(qApp, SIGNAL(damageEvent(Qt::HANDLE &, short &, short &, unsigned short &, unsigned short &)), this, SLOT(damageEvent(Qt::HANDLE &, short &, short &, unsigned short &, unsigned short &)));
 
-    // Create a close button for the window
-    closeButton = new MButton(controller);
+    titleBarLayout = new MLayout(controller);
+    titleBarLayout->setContentsMargins(0,0,0,0);
+    titleBarPolicy = new MLinearLayoutPolicy(titleBarLayout, Qt::Horizontal);
+
+    titleLabel = new MLabel(controller);
+    titleLabel->setContentsMargins(0,0,0,0);
+    titleLabel->setAlignment(Qt::AlignLeft);
+    titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+    titleBarPolicy->addItem(titleLabel);
+
+    closeButton = new MButton();
     closeButton->setViewType(MButton::iconType);
     connect(closeButton, SIGNAL(clicked()), controller, SLOT(close()));
+    titleBarPolicy->addItem(closeButton);
+
+    controller->setLayout(titleBarLayout);
 
     // Enable or disable reception of damage events based on whether the switcher button is on the screen or not
     connect(button, SIGNAL(displayEntered()), this, SLOT(setOnDisplay()));
     connect(button, SIGNAL(displayExited()), this, SLOT(unsetOnDisplay()));
+
+    if (iconGeometryAtom == 0) {
+        // Get the icon geometry X11 Atom if it doesn't exist yet
+        iconGeometryAtom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_WM_ICON_GEOMETRY", False);
+    }
+
+    // Set up the timer for updating the icon geometry
+    updateXWindowIconGeometryTimer.setSingleShot(true);
+    updateXWindowIconGeometryTimer.setInterval(ICON_GEOMETRY_UPDATE_INTERVAL);
+    connect(&updateXWindowIconGeometryTimer, SIGNAL(timeout()), this, SLOT(updateXWindowIconGeometry()));
 }
 
 SwitcherButtonView::~SwitcherButtonView()
@@ -72,17 +99,11 @@
 #endif
 }
 
-void SwitcherButtonView::setGeometry(const QRectF &rect)
-{
-    MButtonView::setGeometry(rect);
-
-    closeButton->setGeometry(closeRect());
-}
-
 void SwitcherButtonView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *) const
 {
     // Store the painter state
     painter->save();
+    painter->setRenderHint(QPainter::SmoothPixmapTransform);
 
     // Rotate the thumbnails and adjust their size if the screen
     // has been rotated
@@ -95,7 +116,7 @@
     }
 
     QPoint pos;
-    QPoint iconPos = style()->iconPosition().toPoint();
+    QPoint iconPos(thumbnailPosition());
     QRect source(0, 0, qWindowPixmap.width(), qWindowPixmap.height());
     switch (manager->orientationAngle()) {
         case M::Angle90:
@@ -131,6 +152,9 @@
 
     // Restore the painter state
     painter->restore();
+
+    // Update the X window _NET_WM_ICON_GEOMETRY property if necessary
+    updateXWindowIconGeometryIfNecessary();
 }
 
 void SwitcherButtonView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *) const
@@ -144,49 +168,31 @@
         container->draw(QRect(QPoint(0, 0), size().toSize()), painter);
     }
 
-    // Draw text
-    const QString text(controller->text());
-    if (!text.isEmpty() && controller->isTextVisible()) {
-        QFont font = style()->font();
-        painter->setFont(font);
-        painter->setPen(style()->textColor());
-        painter->setOpacity(style()->textOpacity());
-        painter->drawText(titleRect(), Qt::AlignLeft | Qt::ElideRight, text);
-    }
-
     // Restore the painter state
     painter->restore();
 }
 
-QRectF SwitcherButtonView::iconRect() const
-{
-    return QRectF(style()->iconPosition(), style()->iconSize());
-}
-
-QRectF SwitcherButtonView::titleRect() const
+void SwitcherButtonView::translateCloseButton()
 {
-    QFontMetrics fm(style()->font());
-    QRectF close = closeRect();
-    QRectF rect = iconRect();
-    rect.setTopLeft(rect.topLeft() - QPointF(0, fm.height()));
-    rect.setBottomRight(rect.topRight() + QPointF(-(close.width() + 2 * style()->textMarginLeft()), fm.height()));
-    rect.translate(style()->textMarginLeft(), -style()->textMarginBottom());
-    return rect;
+    int verticalOffset = -style()->closeButtonVOffset();
+    int horizontalOffset = style()->closeButtonHOffset();
+    // Horizontal offset needs to be handled differently for different layout directions
+    if (MApplication::layoutDirection() == Qt::RightToLeft) {
+        horizontalOffset = -horizontalOffset;
+    }
+    closeButton->translate(horizontalOffset, verticalOffset);
 }
 
-QRectF SwitcherButtonView::closeRect() const
+QRectF SwitcherButtonView::boundingRect() const
 {
-    QRectF icon = iconRect();
-    QRectF rect;
-    rect.setX(icon.right() - closeButton->preferredWidth());
-    rect.setY(icon.top() + style()->closeButtonVerticalPosition());
-    rect.setSize(closeButton->preferredSize());
-    return rect;
+    int titleLabelHeight = titleLabel->size().height();
+    int thumbnailHeight = style()->iconSize().height();
+    return QRectF(0, 0, style()->iconSize().width(), thumbnailHeight + titleLabelHeight);
 }
 
-QRectF SwitcherButtonView::boundingRect() const
+QPoint SwitcherButtonView::thumbnailPosition() const
 {
-    return iconRect().united(titleRect()).united(closeRect());
+    return QPoint(0, titleLabel->size().height());
 }
 
 void SwitcherButtonView::applyStyle()
@@ -201,9 +207,12 @@
         } else {
             closeButton->hide();
         }
+        titleLabel->setObjectName("SwitcherButtonTitleLabelDetailview");
+
     } else {
         closeButton->setObjectName("CloseButtonOverview");
         closeButton->show();
+        titleLabel->setObjectName("SwitcherButtonTitleLabelOverview");
     }
     closeButton->setIconID(style()->closeIcon());
 
@@ -219,6 +228,10 @@
         update();
     }
     updateViewMode();
+
+    translateCloseButton();
+
+    titleLabel->setText(model()->text());
 }
 
 void SwitcherButtonView::updateViewMode()
@@ -247,10 +260,10 @@
         if (member == SwitcherButtonModel::XWindow && model()->xWindow() != 0) {
             updateXWindowPixmap();
             update();
-        }
-
-        if (member == SwitcherButtonModel::ViewMode) {
+        } else if (member == SwitcherButtonModel::ViewMode) {
             updateViewMode();
+        } else if(member == SwitcherButtonModel::Text) {
+            titleLabel->setText(model()->text());
         }
     }
 }
@@ -316,9 +329,14 @@
     Q_UNUSED(y);
     Q_UNUSED(width);
     Q_UNUSED(height);
+#ifdef Q_WS_X11
     if (xWindowPixmapDamage == damage) {
+        X11Wrapper::XDamageSubtract(QX11Info::display(), xWindowPixmapDamage, NULL, NULL);
         update();
     }
+#else
+    Q_UNUSED(damage);
+#endif
 }
 
 void SwitcherButtonView::setOnDisplay()
@@ -337,7 +355,7 @@
 void SwitcherButtonView::createDamage()
 {
 #ifdef Q_WS_X11
-    if (onDisplay && xWindowPixmap != 0) {
+    if (onDisplay && model()->xWindow() != 0) {
         // Register the pixmap for XDamage events
         xWindowPixmapDamage = X11Wrapper::XDamageCreate(QX11Info::display(), model()->xWindow(), XDamageReportNonEmpty);
     }
@@ -354,4 +372,35 @@
 #endif
 }
 
+void SwitcherButtonView::updateXWindowIconGeometryIfNecessary() const
+{
+    if (updatedXWindowIconPosition != controller->mapToScene(thumbnailPosition())) {
+        // Update the icon geometry in a moment if an update has not already been requested
+        if (!updateXWindowIconGeometryTimer.isActive()) {
+            updateXWindowIconGeometryTimer.start();
+        }
+    }
+}
+
+void SwitcherButtonView::updateXWindowIconGeometry()
+{
+    // Get the geometry of the Switcher Button in scene coordinates
+    QPointF topLeft(controller->mapToScene(thumbnailPosition()));
+    QPointF bottomRight(controller->mapToScene(thumbnailPosition().x() + style()->iconSize().width(), thumbnailPosition().y() + style()->iconSize().height()));
+    QRectF iconSceneGeometry;
+    iconSceneGeometry.setCoords(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y());
+    iconSceneGeometry = iconSceneGeometry.normalized();
+
+    // Replace the old X icon geometry property for the window with iconGeometry, which consists of 4 unsigned ints (32 bits)
+    unsigned int iconGeometry[4];
+    iconGeometry[0] = iconSceneGeometry.x();
+    iconGeometry[1] = iconSceneGeometry.y();
+    iconGeometry[2] = iconSceneGeometry.width();
+    iconGeometry[3] = iconSceneGeometry.height();
+    X11Wrapper::XChangeProperty(QX11Info::display(), model()->xWindow(), iconGeometryAtom, XA_CARDINAL, sizeof(unsigned int) * 8, PropModeReplace, (unsigned char *)&iconGeometry, 4);
+
+    // Store which position has already been updated
+    updatedXWindowIconPosition = topLeft;
+}
+
 M_REGISTER_VIEW_NEW(SwitcherButtonView, SwitcherButton)
--- src/home/switcherbuttonview.h
+++ src/home/switcherbuttonview.h
@@ -20,12 +20,16 @@
 #define SWITCHERBUTTONVIEW_H
 
 #include <MButtonView>
+#include <QTimer>
 #include "switcherbuttonmodel.h"
 #include "switcherbuttonstyle.h"
 #include "x11wrapper.h"
 
 class SwitcherButton;
 class MButton;
+class MLayout;
+class MLinearLayoutPolicy;
+class MLabel;
 
 /*!
  * \class SwitcherButtonView
@@ -55,9 +59,11 @@
     virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
     virtual QRectF boundingRect() const;
     virtual void applyStyle();
-    void setGeometry(const QRectF &rect);
     //! \reimp_end
 
+    //! Returns the bounding rectangle of the thumbnail
+    QRectF thumbnailRect() const;
+
 protected slots:
     //! \reimp
     virtual void updateData(const QList<const char *>& modifications);
@@ -83,6 +89,12 @@
      */
     void unsetOnDisplay();
 
+private slots:
+    /*!
+     * \brief Updates the _NET_WM_ICON_GEOMETRY X property for the Window
+     */
+    void updateXWindowIconGeometry();
+
 protected:
     /*!
      * Creates an X damage structure based on the current X window pixmap.
@@ -103,16 +115,18 @@
      */
     virtual void updateXWindowPixmap();
 
-    /*! 
-     * Updates the button style to reflect the current view mode.
-     */
-    void updateViewMode();
+private:
+    //! Starts a timer for updating the icon geometry if the icon geometry has changed after the last update
+    void updateXWindowIconGeometryIfNecessary() const;
+
+    //! Translates close button according to offset attributes in style.
+    void translateCloseButton();
 
-    //! Returns the bounding rectangle of the icon (thumbnail)
-    QRectF iconRect() const;
+    //! Returns the thumbnail position in parent coordinates.
+    QPoint thumbnailPosition() const;
 
-    //! Returns the bounding rectangle of the close button
-    QRectF closeRect() const;
+    //! Updates the button style to reflect the current view mode.
+    void updateViewMode();
 
     //! Returns the bounding rectangle of the window title
     QRectF titleRect() const;
@@ -128,6 +142,9 @@
     // The height of the navigation bar for cropping the thumbnail
     static const int NAVIGATION_BAR_HEIGHT;
 
+    // Time between icon geometry updates in milliseconds
+    static const int ICON_GEOMETRY_UPDATE_INTERVAL;
+
     //! SwitcherButton controller
     SwitcherButton *controller;
 
@@ -146,9 +163,31 @@
     //! Button for closing the window
     MButton *closeButton;
 
+    //! Title label
+    MLabel *titleLabel;
+
     //! Whether the button is being displayed or not
     bool onDisplay;
 
+    //! Title bar layout
+    MLayout *titleBarLayout;
+
+    //! Policy for title bar layout
+    MLinearLayoutPolicy *titleBarPolicy;
+
+    //! Timer for updating the icon's position in scene coordination
+    mutable QTimer updateXWindowIconGeometryTimer;
+
+    //! The icon's position in scene coordinates
+    QPointF updatedXWindowIconPosition;
+
+    //! X11 Atom for the icon geometry
+    static Atom iconGeometryAtom;
+
+#ifdef UNIT_TEST
+    friend class Ut_SwitcherButtonView;
+#endif
+
     Q_DISABLE_COPY(SwitcherButtonView);
 };
 
--- src/home/switcherstyle.h
+++ src/home/switcherstyle.h
@@ -29,25 +29,6 @@
     Q_OBJECT
     M_STYLE(SwitcherStyle)
 
-    /*! Defines how much the focused switcher button will be scaled */
-    M_STYLE_ATTRIBUTE(qreal, scaleFactor, ScaleFactor)
-
-    /*!
-     * Defines how much extra the focused switcher button will move 
-     * horizontally "out of the way".
-     */
-    M_STYLE_ATTRIBUTE(qreal, fastForward, FastForward)
-
-    /*!
-     * Defines how much the focused switcher button will rotate at maximum 
-     * during horizontal movement
-     */
-    M_STYLE_ATTRIBUTE(qreal, itemRotation, ItemRotation)
-    /*!
-     * Defines how mush the items will over lap when they are stationary
-     */
-    M_STYLE_ATTRIBUTE(qreal, itemOverLap, ItemOverLap)
-
      /*!
      * Defines horizontal spacing between switcher buttons.
      */
--- src/home/switcherview.cpp
+++ src/home/switcherview.cpp
@@ -42,7 +42,6 @@
 #include <algorithm>
 #include "pagedviewport.h"
 
-static qreal calculateCenterCorrection(qreal value, qreal scaleFactor);
 static const qreal HALF_PI = M_PI / 2.0;
 static const qreal MAX_Z_VALUE = 1.0;
 
@@ -54,6 +53,7 @@
     switcher->setLayout(mainLayout);
 
     connect(viewport, SIGNAL(pageChanged(int)), this, SLOT(updateFocusedButton(int)));
+    connect(MainWindow::instance()->sceneManager(), SIGNAL(orientationChanged(M::Orientation)), this, SLOT(updateButtons()));
 
     // We have custom values for this view port in the style
     viewport->setObjectName("SwitcherViewport");
@@ -63,119 +63,33 @@
     pannedLayout->setContentsMargins(0, 0, 0, 0);
 
     overviewPolicy = new MGridLayoutPolicy(pannedLayout);
-    overviewPolicy->setSpacing(0);
     overviewPolicy->setObjectName("OverviewPolicy");
 
     detailPolicy = new MLinearLayoutPolicy(pannedLayout, Qt::Horizontal);
-    detailPolicy->setSpacing(0);
     detailPolicy->setObjectName("DetailviewPolicy");
 
+    viewport->setAutoRange(false);
     viewport->setWidget(pannedWidget);
 
     viewport->positionIndicator()->setObjectName("SwitcherOverviewPageIndicator");
 
     focusedSwitcherButton = 0;
-    firstButtonPriority = WindowInfo::Normal;
 }
 
 SwitcherView::~SwitcherView()
 {
+    removeButtonsFromLayout();
 }
 
 void SwitcherView::panningStopped()
 {
     if (model()->switcherMode() == SwitcherModel::Detailview) {
-        if (model()->buttons().empty()) {
-            return;
-        }
-        model()->buttons().at(focusedSwitcherButton)->model()->setViewMode(SwitcherButtonModel::Large);
         for (int i = 0; i < model()->buttons().count(); i++) {
-            if (i != focusedSwitcherButton) {
-                model()->buttons().at(i)->model()->setViewMode(SwitcherButtonModel::Medium);
-            }
+            model()->buttons().at(i)->model()->setViewMode(i == focusedSwitcherButton ? SwitcherButtonModel::Large : SwitcherButtonModel::Medium);
         }
     }
 }
 
-void SwitcherView::animateDetailView(const QPointF &pannedPos)
-{
-    qreal viewportWidthHalf = geometry().width() / 2;
-    for (int i = 0; i < pannedLayout->count(); i++) {
-        SwitcherButton* widget = dynamic_cast<SwitcherButton*> (pannedLayout->itemAt(i));
-        widget->model()->setViewMode(SwitcherButtonModel::Medium);
-        QRectF widgetGeometry = widget->geometry();
-
-        // Pre calculate some variables for speed and readability
-        qreal center = pannedPos.x() + viewportWidthHalf;
-        qreal widgetCenter = widgetGeometry.left() + (widgetGeometry.width() / 2);
-        qreal distanceFromCenter = widgetCenter - center;
-        qreal normalizedDistFromCenter = distanceFromCenter / viewportWidthHalf;
-        // sined + the curve "wave length" fitted to the width
-        qreal transformationPath = sin(normalizedDistFromCenter * M_PI);
-
-        /*
-         The scale factor is 1 when the widget's center is at the center of the screen
-         and style()->scaleFactor() when widgets center is at the edge of the screen.
-         The sin curve will be phase shifted (== times HALF_PI) and 'amplitude capped'
-         so that we scale factor will behave as describe above.
-         */
-        qreal amplitudeLimitation = 1 - style()->scaleFactor();
-        qreal scaleFactor = 1 - amplitudeLimitation * sin((abs(distanceFromCenter) / (viewportWidthHalf)) * HALF_PI);
-
-        /*
-         Calculate center correction factors as the scaling will expand the button
-         to right and south.
-         */
-        qreal xCentered = calculateCenterCorrection(widgetGeometry.width(), scaleFactor);
-        qreal yCentered = calculateCenterCorrection(widgetGeometry.height(), scaleFactor);
-        /*
-         As the unemphasized items are scaled downwards they need to be horizontally
-         shifted closer to the emphasized item, otherwise a big gap will appear in
-         between the items
-         */
-        qreal overLapCurve = sin(normalizedDistFromCenter * HALF_PI) * style()->itemOverLap();
-        qreal scaleInducedShift = widgetGeometry.width() * (1 - scaleFactor);
-        qreal shiftFactor = overLapCurve + scaleInducedShift;
-        if (distanceFromCenter < 0) {
-            xCentered -= shiftFactor;
-        } else {
-            xCentered += shiftFactor;
-        }
-
-        // The horizontal movement of the focused item is "fast-forwarded"
-        if (focusedSwitcherButton == i) {
-            xCentered -= style()->fastForward() * transformationPath;
-        }
-
-        QTransform positionAndScale;
-        positionAndScale.translate(-xCentered, -yCentered);
-        positionAndScale.scale(scaleFactor, scaleFactor);
-        widget->setTransform(positionAndScale);
-
-        /*
-         As the distance of the widget from the center of the viewport is
-         normalized to 0...1 (0 meaning that the widget is in the center)
-         we make sure that the the widget in the center has the highest Z order
-         */
-        widget->setZValue(MAX_Z_VALUE - abs(distanceFromCenter));
-
-        // Rotate only if the item rotation is non-zero 
-        if (style()->itemRotation() != 0) {
-            int angle = 0.0;
-            // The angle is only valid when we are with-in the viewport.
-            if (abs(distanceFromCenter) / viewportWidthHalf < 1.0) {
-                angle = style()->itemRotation() * transformationPath;
-            }
-            QTransform rotation;
-            rotation.translate(0, widgetGeometry.height() / 2);
-            rotation.rotate(angle, Qt::YAxis);
-            rotation.translate(0, -widgetGeometry.height() / 2);
-            widget->setTransform(rotation, true);
-        }
-
-    }
-}
-
 void SwitcherView::setupModel()
 {
     MWidgetView::setupModel();
@@ -185,15 +99,12 @@
 void SwitcherView::applySwitcherMode()
 {
     if (model()->switcherMode() == SwitcherModel::Detailview) {
-        disconnect(MainWindow::instance()->sceneManager(), 0, this, 0);
-        pannedLayout->setPolicy(detailPolicy);
-        connect(viewport, SIGNAL(positionChanged(QPointF)), this, SLOT(animateDetailView(QPointF)));
         connect(viewport, SIGNAL(panningStopped()), this, SLOT(panningStopped()));
+
+        pannedLayout->setPolicy(detailPolicy);
         controller->setObjectName("DetailviewSwitcher");
     } else {
         disconnect(viewport, 0, this, 0);
-        connect(MainWindow::instance()->sceneManager(), SIGNAL(orientationChangeFinished(M::Orientation)), this, SLOT(updateButtons()));
-        connect(MainWindow::instance()->sceneManager(), SIGNAL(orientationAboutToChange(M::Orientation)), this, SLOT(hideButtons()));
 
         pannedLayout->setPolicy(overviewPolicy);
         controller->setObjectName("OverviewSwitcher");
@@ -208,49 +119,19 @@
     const char *member;
     foreach(member, modifications) {
         if (member == SwitcherModel::Buttons) {
-            if (model()->buttons().isEmpty()) {
-                // Reset the priority if the model is empty
-                firstButtonPriority = WindowInfo::Normal;
-            } else {
-                SwitcherButton *firstButton = model()->buttons().first().data();
-
-                // If the first button's priority has risen pan the view to show it
-                if (firstButton->windowPriority() < firstButtonPriority) {
-                    viewport->panToPage(0);
-                }
-
-                firstButtonPriority = firstButton->windowPriority();
-            }
-
             updateButtons();
-        }
-
-        if (member == SwitcherModel::SwitcherMode) {
+        } else if (member == SwitcherModel::SwitcherMode) {
             applySwitcherMode();
         }
     }
 }
 
-void SwitcherView::hideButtons()
-{
-    foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
-        button.data()->setVisible(false);
-    }
-
-    // Remove all widgets from the layout (do not destroy them)
-    while (pannedLayout->count() > 0) {
-        pannedLayout->removeAt(0);
-    }
-}
-
 void SwitcherView::updateButtons()
 {
     focusedSwitcherButton = std::min(focusedSwitcherButton, model()->buttons().size() - 1);
     focusedSwitcherButton = std::max(focusedSwitcherButton, 0);
 
-    while (pannedLayout->count() > 0) {
-        pannedLayout->removeAt(0);
-    }
+    removeButtonsFromLayout();
 
     /* Recreate the GridLayoutPolicy to keep the pannedWidget's size correct.
        TODO: Can hopefully be removed, pending on bug 165683 */
@@ -262,8 +143,6 @@
     overviewPolicy->setSpacing(0);
     overviewPolicy->setObjectName("OverviewPolicy");
 
-    delete tmp;
-
     // Add widgets from the model to the layout
     foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
         detailPolicy->addItem(button.data());
@@ -272,36 +151,45 @@
 
     updateButtonModesAndPageCount();
 
-    foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
-        button.data()->setVisible(true);
-    }
+    delete tmp;
 }
 
 void SwitcherView::updateButtonModesAndPageCount()
 {
-    int pages;
+    int pages = 0;
+    qreal range = 0;
 
     int buttonCount = model()->buttons().count();
-    if (model()->switcherMode() == SwitcherModel::Detailview) {
-        foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
-            button.data()->setObjectName("DetailviewButton");
-            button.data()->model()->setViewMode(SwitcherButtonModel::Medium);
-        }
-        pages = model()->buttons().count();
-    } else {
-        foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
-            button.data()->setObjectName("OverviewButton");
-            if (buttonCount < 3) {
-                button.data()->model()->setViewMode(SwitcherButtonModel::Large);
-            } else {
+    if (buttonCount > 0) {
+        if (model()->switcherMode() == SwitcherModel::Detailview) {
+            foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
+                button.data()->setObjectName("DetailviewButton");
                 button.data()->model()->setViewMode(SwitcherButtonModel::Medium);
             }
+
+            qreal buttonWidth = model()->buttons().first()->preferredSize().width();
+            pages = buttonCount;
+            range = (buttonCount - 1) * (buttonWidth + (geometry().width() - buttonWidth) / 4) + geometry().width();
+        } else {
+            SwitcherButtonModel::ViewModeType mode = buttonCount < 3 ? SwitcherButtonModel::Large : SwitcherButtonModel::Medium;
+            foreach (QSharedPointer<SwitcherButton> button, model()->buttons()) {
+                button.data()->setObjectName("OverviewButton");
+                button.data()->model()->setViewMode(mode);
+            }
+
+            pages = ceilf((qreal)buttonCount / (style()->columnsPerPage() * style()->rowsPerPage()));
+            range = pages * geometry().width();
         }
-        pages = ceilf((qreal)model()->buttons().count()/(style()->columnsPerPage()*style()->rowsPerPage()));
     }
 
+    // First update the page count
     viewport->updatePageCount(pages);
 
+    // Then set the range - this starts the integration and pans
+    // the view to the correct page in case we were on the last
+    // page and closed the last button
+    viewport->setRange(QRectF(0, 0, range, 0));
+
     updateContentsMarginsAndSpacings();
 }
 
@@ -324,99 +212,97 @@
 
 void SwitcherView::updateContentsMarginsAndSpacings()
 {
-    int buttonCount = model()->buttons().count();
-    int colsPerPage = style()->columnsPerPage();
-    int rows = style()->rowsPerPage();
-
-    qreal topMargin, bottomMargin, leftMargin, rightMargin;
-
-    if (buttonCount == 0 || colsPerPage == 0 || rows == 0) {
+    if (style()->columnsPerPage() > 0 && style()->rowsPerPage() > 0 && model()->buttons().count() > 0) {
+        updateDetailViewContentsMarginsAndSpacings();
+        updateOverviewContentsMarginsAndSpacings();
+    } else {
         detailPolicy->setContentsMargins(0, 0, 0, 0);
         overviewPolicy->setContentsMargins(0, 0, 0, 0);
-        return;
     }
+}
 
-    SwitcherButton* button = model()->buttons().first().data();
-    qreal buttonWidth = button->preferredSize().width();
-    qreal buttonHeight = button->preferredSize().height();
-
-    qreal detailMargin = (geometry().width() - buttonWidth) / 2;
+void SwitcherView::updateDetailViewContentsMarginsAndSpacings()
+{
+    SwitcherButton *button = model()->buttons().first().data();
 
-    // The margin for centering vertically
-    qreal verticalContentMargin = (geometry().height() - buttonHeight) / 2;
+    // The leftmost and the rightmost items need extra space on their sides to get them centered: the rest need spacing between them
+    qreal horizontalMargin = (geometry().width() - button->preferredSize().width()) / 2;
+    qreal verticalMargin = (geometry().height() - button->preferredSize().height()) / 2;
+    detailPolicy->setContentsMargins(horizontalMargin, verticalMargin, horizontalMargin, verticalMargin);
+    detailPolicy->setHorizontalSpacing(horizontalMargin / 2);
+}
 
-    detailPolicy->setContentsMargins(detailMargin, verticalContentMargin,
-                                     detailMargin, verticalContentMargin);
+void SwitcherView::updateOverviewContentsMarginsAndSpacings()
+{
+    SwitcherButton *button = model()->buttons().first().data();
+    int buttonCount = model()->buttons().count();
+    int colsPerPage = style()->columnsPerPage();
+    int rows = style()->rowsPerPage();
 
-    overviewPolicy->getContentsMargins(&leftMargin, &topMargin,
-                                       &rightMargin, &bottomMargin);
+    // Calculate margins for the overview
+    qreal topMargin, bottomMargin, leftMargin, rightMargin;
+    overviewPolicy->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
 
     int columns = qMin(overviewPolicy->columnCount(), style()->columnsPerPage());
-    qreal effectiveButtonsWidth = (columns * buttonWidth) + ((columns - 1) * style()->buttonHorizontalSpacing());
+    qreal effectiveButtonsWidth = (columns * button->preferredSize().width()) + ((columns - 1) * style()->buttonHorizontalSpacing());
 
     leftMargin = (geometry().width() - effectiveButtonsWidth) / 2;
     rightMargin = leftMargin;
 
     /*
        If the last page is missing buttons i.e. it is not full, we add extra margins to it
-       so that the pageing works
+       so that the paging works
      */
     if (buttonCount > (style()->columnsPerPage() * style()->rowsPerPage())) {
         int lastPageButtonCount = buttonCount % (style()->columnsPerPage() * style()->rowsPerPage());
         if (lastPageButtonCount > 0 && lastPageButtonCount < style()->columnsPerPage()) {
             // Compensate the missing buttons
             int missingButtonCount = style()->columnsPerPage() - lastPageButtonCount;
-            rightMargin = leftMargin + buttonWidth * missingButtonCount;
+            rightMargin = leftMargin + button->preferredSize().width() * missingButtonCount;
             // Also add the spacings
             rightMargin += missingButtonCount * style()->buttonHorizontalSpacing();
         }
     }
 
-    if( buttonCount < 3 ) {
-        topMargin = verticalContentMargin;
-        bottomMargin = verticalContentMargin;
+    if (buttonCount < 3) {
+        // One or two buttons fit on a single row so just center them vertically
+        topMargin = (geometry().height() - button->preferredSize().height()) / 2;
+        bottomMargin = topMargin;
     }
 
-    overviewPolicy->setContentsMargins(leftMargin, topMargin,
-                                       rightMargin, bottomMargin);
+    overviewPolicy->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin);
 
-    for(int column = 0; column < overviewPolicy->columnCount(); column++) {
-        if ((column % colsPerPage) == colsPerPage - 1) {
-            overviewPolicy->setColumnSpacing(column, leftMargin * 2);
-        } else {
-            overviewPolicy->setColumnSpacing(column, style()->buttonHorizontalSpacing());
-        }
+    // Add horizontal spacing for all columns except the last one
+    for (int column = 0; column < overviewPolicy->columnCount(); column++) {
+        overviewPolicy->setColumnSpacing(column, (column % colsPerPage) != (colsPerPage - 1) ? style()->buttonHorizontalSpacing() : (leftMargin * 2));
     }
 
-    for(int row = 0; row < rows; row++) {
-        // add vertical spacing for all but last row
-        if(row < rows - 1){
-            overviewPolicy->setRowSpacing(row, style()->buttonVerticalSpacing());
-        }
+    // Add vertical spacing for all rows except the last one
+    for (int row = 0; row < rows - 1; row++) {
+        overviewPolicy->setRowSpacing(row, style()->buttonVerticalSpacing());
     }
-
 }
 
 void SwitcherView::addButtonInOverviewPolicy(QSharedPointer<SwitcherButton> button)
 {
     int colsPerPage = style()->columnsPerPage();
     int rows = style()->rowsPerPage();
-    // just a precautionary measure so that we do not divide with zero later on
-    if (rows == 0 || colsPerPage == 0) {
-        return;
-    }
-    int location = model()->buttons().indexOf(button);
-    int page = location / (colsPerPage * rows);
-    int row = (location / colsPerPage) % rows;
-    int column = (location % colsPerPage) + (page * colsPerPage);
+    if (rows > 0 && colsPerPage > 0) {
+        int location = model()->buttons().indexOf(button);
+        int page = location / (colsPerPage * rows);
+        int row = (location / colsPerPage) % rows;
+        int column = (location % colsPerPage) + (page * colsPerPage);
 
-    overviewPolicy->addItem(button.data(), row, column);
+        overviewPolicy->addItem(button.data(), row, column);
+    }
 }
 
-static qreal calculateCenterCorrection(qreal value, qreal scaleFactor)
+void SwitcherView::removeButtonsFromLayout()
 {
-    return (value * (scaleFactor - 1)) / 2.0;
+    // Remove all buttons from the layout and set parents to null (do not destroy them)
+    for (int i = 0, count = pannedLayout->count(); i < count; i++) {
+        static_cast<SwitcherButton *>(pannedLayout->takeAt(0))->setParentItem(0);
+    }
 }
 
-
 M_REGISTER_VIEW_NEW(SwitcherView, Switcher)
--- src/home/switcherview.h
+++ src/home/switcherview.h
@@ -66,9 +66,6 @@
     //! \endcond
 
 private slots:
-    /*! Monitors the movement of the pannable viewport */
-    void animateDetailView(const QPointF &pannedPos);
-
     /*! Listens for page change in the paged viewport */
     void updateFocusedButton(int currentPage);
 
@@ -78,9 +75,6 @@
     /*! Update all buttons in the layout policies */
     void updateButtons();
 
-    /*! Remove all buttons from the layout and set them invisible */
-    void hideButtons();
-
 private:
 
     /*! Adds a button in the correct position in the overview layout policy */
@@ -89,12 +83,23 @@
     /*! Updates the content margin and spacings of the layout policies */
     void updateContentsMarginsAndSpacings();
 
+    /*! Updates the content margins and spacings of the detail view layout policy */
+    void updateDetailViewContentsMarginsAndSpacings();
+
+    /*! Updates the content margins and spacings of the overview layout policy */
+    void updateOverviewContentsMarginsAndSpacings();
+
     /*! Updates the modes of the buttons and the page count according to the switcher mode */
     void updateButtonModesAndPageCount();
 
     /*! Selects the layout policy and sets up switcher mode dependent signals */
     void applySwitcherMode();
 
+    /*! Remove all buttons from layout and set parents to NULL
+     * Parents are set to NULL to avoid double deletion as buttons are QSharedPointer's in model
+     */
+    void removeButtonsFromLayout();
+
     /*! The switcher controller */
     Switcher *controller;
 
@@ -116,9 +121,6 @@
     /*! The current focused switcher button */
     int focusedSwitcherButton;
 
-    /*! Keep track of the first button's priority */
-    WindowInfo::WindowPriority firstButtonPriority;
-
 #ifdef UNIT_TEST
     // to test snapIndexChanged effects
     friend class Ut_SwitcherView;
--- src/home/windowinfo.cpp
+++ src/home/windowinfo.cpp
@@ -16,44 +16,76 @@
 ** of this file.
 **
 ****************************************************************************/
-
 #include <cstring>
 #include "windowinfo.h"
+#include "x11wrapper.h"
+#include <QX11Info>
 
-WindowInfo::WindowInfo(QString &title, Window window, XWindowAttributes windowAttributes,
-                       Pixmap icon, WindowPriority priority) :
-    title_(title), windowPriority_(priority), window_(window),
-    attributes_(windowAttributes), pixmap_(icon)
-{
+
+static bool atomsInitialized;
+
+Atom WindowInfo::TypeAtom;
+Atom WindowInfo::StateAtom;
+Atom WindowInfo::NormalAtom;
+Atom WindowInfo::DesktopAtom;
+Atom WindowInfo::NotificationAtom;
+Atom WindowInfo::DialogAtom;
+Atom WindowInfo::CallAtom;
+Atom WindowInfo::DockAtom;
+Atom WindowInfo::MenuAtom;
+Atom WindowInfo::SkipTaskbarAtom;
+Atom WindowInfo::NameAtom;
+
+WindowInfo::WindowInfo(Window window)
+{    
+    if (!atomsInitialized) {
+        Display *dpy = QX11Info::display();
+        WindowInfo::TypeAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+        WindowInfo::StateAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_STATE", False);
+        WindowInfo::NormalAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);    
+        WindowInfo::DesktopAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
+        WindowInfo::NotificationAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
+        WindowInfo::DialogAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+        WindowInfo::CallAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_CALL", False);
+        WindowInfo::DockAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
+        WindowInfo::MenuAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
+        WindowInfo::SkipTaskbarAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
+        WindowInfo::NameAtom = X11Wrapper::XInternAtom(dpy, "_NET_WM_NAME", False);
+        atomsInitialized = true;
+    }
+    d = new WindowData;
+    d->window = window;
+    updateWindowTitle();
+    updateWindowProperties();
 }
 
-WindowInfo::~WindowInfo()
+WindowInfo::WindowInfo()
 {
+    d = new WindowData;
 }
 
-const QString &WindowInfo::title() const
+WindowInfo::~WindowInfo()
 {
-    return title_;
 }
 
-WindowInfo::WindowPriority WindowInfo::windowPriority() const
+const QString& WindowInfo::title() const
 {
-    return windowPriority_;
+    return d->title;
 }
 
 Window WindowInfo::window() const
 {
-    return window_;
+    return d->window;
 }
 
-XWindowAttributes WindowInfo::windowAttributes() const
+QList<Atom> WindowInfo::types() const
 {
-    return attributes_;
+    return d->types;
 }
 
-Pixmap WindowInfo::icon() const
+QList<Atom> WindowInfo::states() const
 {
-    return pixmap_;
+    return d->states;
 }
 
 bool operator==(const WindowInfo &wi1, const WindowInfo &wi2)
@@ -61,3 +93,51 @@
     return wi1.window() == wi2.window();
 }
 
+bool WindowInfo::updateWindowTitle()
+{
+    Display *dpy = QX11Info::display();
+    XTextProperty textProperty;
+    bool updated = false;
+    int result = X11Wrapper::XGetTextProperty(dpy, d->window, &textProperty, WindowInfo::NameAtom);
+    if (result == 0) {
+        result = X11Wrapper::XGetWMName(dpy, d->window, &textProperty);
+    }
+
+    if (result != 0) {
+        d->title = QString::fromUtf8((const char *)textProperty.value);
+        X11Wrapper::XFree(textProperty.value);
+        updated = true;
+    }
+    return updated;
+}
+
+void WindowInfo::updateWindowProperties()
+{
+    d->types = getWindowProperties(d->window, WindowInfo::TypeAtom);
+    d->states = getWindowProperties(d->window, WindowInfo::StateAtom);
+}
+
+QList<Atom> WindowInfo::getWindowProperties(Window winId, Atom propertyAtom, long maxCount)
+{
+    QList<Atom> to;
+    Display *dpy = QX11Info::display();
+
+    Atom actualType;
+    int actualFormat;
+    unsigned long numTypeItems, bytesLeft;
+    unsigned char *typeData = NULL;
+    
+    Status result = X11Wrapper::XGetWindowProperty(dpy, winId, propertyAtom, 0L, maxCount, False, XA_ATOM,
+                                                   &actualType, &actualFormat, 
+                                                   &numTypeItems, &bytesLeft, &typeData);
+
+    if (result == Success) {
+        to.clear();
+        Atom *type = (Atom *)typeData;
+        for (unsigned int n = 0; n < numTypeItems; n++) {
+            to.append(type[n]);
+        }
+        X11Wrapper::XFree(typeData);            
+    }
+    return to;
+}
--- src/home/windowinfo.h
+++ src/home/windowinfo.h
@@ -23,6 +23,37 @@
 #include <QString>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <QVector>
+#include <QExplicitlySharedDataPointer>
+
+/*!
+  The window data is explicitly shared between window info objects through this class
+ */
+class WindowData : public QSharedData
+{
+
+public:
+    //! Constructs a window data object
+    WindowData() {}
+    //! Copy constructor
+    WindowData(const WindowData& source)
+        : QSharedData(source), window(source.window),
+        types(source.types), states(source.states) {}
+    //! Destructor
+    ~WindowData() {}
+
+    //! The X window id
+    Window window;
+
+    //! The title of the window
+    QString title;
+
+    //! The window types associated with this window
+    QList<Atom> types;
+
+    //! The status atoms of this window
+    QList<Atom> states;
+};
 
 /*!
  * WindowInfo is a helper class for storing information about an open window.
@@ -30,24 +61,35 @@
 class WindowInfo
 {
 public:
+
+    // X11 atoms
+    static Atom TypeAtom;
+    static Atom StateAtom;
+    static Atom NormalAtom;
+    static Atom DesktopAtom;
+    static Atom NotificationAtom;
+    static Atom DialogAtom;
+    static Atom CallAtom;
+    static Atom DockAtom;
+    static Atom MenuAtom;
+    static Atom SkipTaskbarAtom;
+    static Atom NameAtom;
+
+
     /*!
-     * Priority values for a window. Smaller value means higher priority.
-     * Values are so that different priorities can later be added.
+     * Constructs a WindowInfo that contains information about an open window.
+     * This is needed to satisfy the Qt's defualt constructed value paradigm in 
+     * its containers.
      */
-    enum WindowPriority {
-        Call = 100,
-        Normal = 500
-    };
+    WindowInfo();
 
     /*!
      * Constructs a WindowInfo that contains information about an open window.
      *
-     * \param title the title of the window
-     * \param window the window
-     * \param windowAttributes the attributes of the window
-     * \param icon the icon of the window
+     * \param window The X window id
      */
-    WindowInfo(QString &title, Window window, XWindowAttributes windowAttributes, Pixmap icon, WindowPriority priority = WindowInfo::Normal);
+    WindowInfo(Window window);
+
 
     /*!
      * Destroys a WindowInfo object.
@@ -62,11 +104,16 @@
     const QString &title() const;
 
     /*!
-     * Gets the priority of the window.
-     *
-     * \return the priority of the window
+     * Gets the types for this window \s WindowType
+     * \return the types
+     */
+    QList<Atom> types() const;
+
+    /*!
+     * Gets the states for this window \s WindowType
+     * \return the states
      */
-    WindowPriority windowPriority() const;
+    QList<Atom> states() const;
 
     /*!
      * Gets the window.
@@ -76,34 +123,25 @@
     Window window() const;
 
     /*!
-     * Gets the attributes of the window.
-     *
-     * \return the attributes of the window
+     * Retrieves the window title. First the title is retrieved with atom _NET_WM_NAME,
+     * if this failes then XGetWMName will be used.
      */
-    XWindowAttributes windowAttributes() const;
-
+    bool updateWindowTitle();
+    
     /*!
-     * Gets the icon of the window.
-     *
-     * \return the icon of the window
+     * Updates the window types and window states from the window manager
      */
-    Pixmap icon() const;
+    void updateWindowProperties();
 
 private:
-    //! The title of the window
-    QString title_;
-
-    //! The priority of the window
-    WindowPriority windowPriority_;
-
-    //! The window
-    Window window_;
-
-    //! The attributes of the window
-    XWindowAttributes attributes_;
+    /*!
+     * Gets the atoms and places them into the list
+     */
+    QList<Atom> getWindowProperties(Window winId, Atom propertyAtom, long maxCount = 16L);
 
-    //! The icon of the window
-    Pixmap pixmap_;
+    //! The explicitly shared data object \c WindowData
+    QExplicitlySharedDataPointer<WindowData> d;
+    
 };
 
 //! Comparison operator for WindowInfo objects
--- src/home/x11helper.cpp
+++ src/home/x11helper.cpp
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#include "x11helper.h"
-#include "x11wrapper.h"
-
-#ifdef Q_WS_X11
-
-QVector<Atom> X11Helper::getNetWmState(Display *display, Window window)
-{
-    QVector<Atom> returnValue;
-
-    Atom actualType;
-    int actualFormat;
-    ulong propertyLength;
-    ulong bytesLeft;
-    uchar *propertyData = 0;
-    Atom netWmState = X11Wrapper::XInternAtom(display, "_NET_WM_STATE", False);
-
-    // Don't read anything, just get the size of the property data
-    if (X11Wrapper::XGetWindowProperty(display, window, netWmState, 0, 0,
-                                       False, XA_ATOM, &actualType, &actualFormat,
-                                       &propertyLength, &bytesLeft, &propertyData) == Success
-            && actualType == XA_ATOM && actualFormat == 32) {
-        returnValue.resize(bytesLeft / sizeof(Atom));
-        X11Wrapper::XFree(propertyData);
-
-        // Fetch all data
-        if (X11Wrapper::XGetWindowProperty(display, window, netWmState, 0, returnValue.size(),
-                                           False, XA_ATOM, &actualType, &actualFormat,
-                                           &propertyLength, &bytesLeft, &propertyData) == Success) {
-            if (propertyLength != (ulong)returnValue.size()) {
-                returnValue.resize(propertyLength);
-            }
-
-            // Put it into the return value
-            if (!returnValue.isEmpty()) {
-                memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
-            }
-            X11Wrapper::XFree(propertyData);
-        } else {
-            returnValue.clear();
-        }
-    }
-
-    return returnValue;
-}
-
-#endif
--- src/home/x11helper.h
+++ src/home/x11helper.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef X11HELPER_H_
-#define X11HELPER_H_
-
-#include <QtGlobal>
-
-#ifdef Q_WS_X11
-
-#include <QVector>
-#include <X11/Xlib.h>
-
-class X11Helper
-{
-public:
-    /*!
-     * Gets a list of the window's _NET_WM_STATE properties.
-     * \param display the display to be used.
-     * \param window the window whose properties are queried.
-     * \return a list of properties.
-     */
-    static QVector<Atom> getNetWmState(Display *display, Window window);
-};
-
-#endif /* Q_WS_X11 */
-
-#endif /* X11HELPER_H_ */
--- src/home/x11wrapper.cpp
+++ src/home/x11wrapper.cpp
@@ -98,3 +98,8 @@
 {
     return ::XSendEvent(display, w, propagate, event_mask, event_send);
 }
+
+void X11Wrapper::XDamageSubtract(Display *dpy, Damage damage, XserverRegion repair, XserverRegion parts)
+{
+    ::XDamageSubtract(dpy, damage, repair, parts);
+}
--- src/home/x11wrapper.h
+++ src/home/x11wrapper.h
@@ -45,6 +45,7 @@
     static XErrorHandler XSetErrorHandler(XErrorHandler handler);
     static int XChangeProperty(Display *display, Window w, Atom property, Atom type, int format, int mode, unsigned char *data, int nelements);
     static Status XSendEvent(Display *display, Window w, Bool propagate, long event_mask, XEvent *event_send);
+    static void XDamageSubtract(Display *dpy, Damage damage, XserverRegion repair, XserverRegion parts);
 };
 
 #endif /* X11WRAPPER_H_ */
--- src/libmeegotouchhome/mdesktopbackgroundextensioninterface.h
+++ src/libmeegotouchhome/mdesktopbackgroundextensioninterface.h
@@ -67,6 +67,13 @@
     virtual void setDesktopInterface(MDesktopInterface &desktopInterface) = 0;
 
     /*!
+     * Tells the extension whether the desktop should be defocused or not.
+     *
+     * \param defocused \c true if the desktop should be defocused, \c false otherwise
+     */
+    virtual void setDefocused(bool defocused) = 0;
+
+    /*!
      * Paints the desktop background using the given painter.
      *
      * \param painter the painter to draw the desktop background with.
--- tests/common_top.pri
+++ tests/common_top.pri
@@ -7,8 +7,9 @@
 DEPENDPATH = $$INCLUDEPATH
 CONFIG += debug meegotouch link_pkgconfig
 PKGCONFIG += contextsubscriber-1.0 \
+    contentaction-0.1 \
     xcomposite
-#    ContentManagerSearchIf
+
 QT += testlib network gui dbus xml
 exists($$[QT_INSTALL_LIBS]/libQtOpenGL.so):QT += opengl
 TEMPLATE = app
@@ -22,9 +23,6 @@
     -fprofile-arcs
 }
 
-# Support for deprecated DuiValueSpace. Remove this define when new ContextSubscriber is used.
-DEFINES += MVALUESPACE_USE_DEPRECATED
-
 DEFINES += M_XDG_DIR=\\\"\"$$M_XDG_DIR\"\\\"
 
 # install tests
--- tests/stubs/homeapplication_stub.h
+++ tests/stubs/homeapplication_stub.h
@@ -29,11 +29,9 @@
 public:
     virtual void HomeApplicationConstructor(int &argc, char **argv);
     virtual void HomeApplicationDestructor();
-    virtual void launchContentSearchService();
     virtual void windowListUpdated(QList<WindowInfo> &windowList);
     virtual void windowVisibilityChanged(Window window);
     virtual bool x11EventFilter(XEvent *event);
-    virtual void updateWindowList();
     virtual void sendStartupNotifications();
 };
 
@@ -49,11 +47,6 @@
 
 }
 
-void HomeApplicationStub::launchContentSearchService()
-{
-    stubMethodEntered("launchContentSearchService");
-}
-
 void HomeApplicationStub::windowListUpdated(QList<WindowInfo> &windowList)
 {
     QList<ParameterBase *> params;
@@ -76,11 +69,6 @@
     return stubReturnValue<bool>("x11EventFilter");
 }
 
-void HomeApplicationStub::updateWindowList()
-{
-    stubMethodEntered("updateWindowList");
-}
-
 void HomeApplicationStub::sendStartupNotifications()
 {
     stubMethodEntered("sendStartupNotifications");
@@ -102,21 +90,11 @@
     gHomeApplicationStub->HomeApplicationDestructor();
 }
 
-void HomeApplication::launchContentSearchService()
-{
-    gHomeApplicationStub->launchContentSearchService();
-}
-
 bool HomeApplication::x11EventFilter(XEvent *event)
 {
     return gHomeApplicationStub->x11EventFilter(event);
 }
 
-void HomeApplication::updateWindowList()
-{
-    gHomeApplicationStub->updateWindowList();
-}
-
 void HomeApplication::sendStartupNotifications()
 {
     gHomeApplicationStub->sendStartupNotifications();
--- tests/stubs/launcher_stub.h
+++ tests/stubs/launcher_stub.h
@@ -29,10 +29,9 @@
   public:
   virtual void LauncherConstructor(LauncherDataStore *dataStore, QGraphicsItem *parent);
   virtual void LauncherDestructor();
-  virtual bool startApplication(const QString &application);
-  virtual bool startMApplication(const QString &serviceName);
   virtual void updatePagesFromDataStore();
   virtual int panToPage(const QString &fileEntryPath);
+  virtual void setFirstPage();
   virtual QSharedPointer<LauncherButton> createLauncherButton(const QString &desktopEntryPath);
   virtual QMap<Launcher::Placement, QString> createPlacementMap(const QHash<QString, QVariant> &desktopEntryPlacements);
   virtual void updateLauncherButton(const QString &desktopEntryPath);
@@ -50,19 +49,6 @@
 void LauncherStub::LauncherDestructor() {
 
 }
-bool LauncherStub::startApplication(const QString &application) {
-  QList<ParameterBase*> params;
-  params.append( new Parameter<QString>(application));
-  stubMethodEntered("startApplication",params);
-  return stubReturnValue<bool>("startApplication");
-}
-
-bool LauncherStub::startMApplication(const QString &serviceName) {
-  QList<ParameterBase*> params;
-  params.append( new Parameter<QString>(serviceName));
-  stubMethodEntered("startMApplication",params);
-  return stubReturnValue<bool>("startMApplication");
-}
 
 void LauncherStub::updatePagesFromDataStore() {
   stubMethodEntered("updatePagesFromDataStore");
@@ -89,6 +75,10 @@
   return stubReturnValue<int>("panToPage");
 }
 
+void LauncherStub::setFirstPage() {
+  stubMethodEntered("setFirstPage");
+}
+
 void LauncherStub::updateLauncherButton(const QString &fileEntryPath) {
   QList<ParameterBase*> params;
   params.append( new Parameter<QString>(fileEntryPath));
@@ -128,14 +118,6 @@
   gLauncherStub->LauncherDestructor();
 }
 
-bool Launcher::startApplication(const QString &application) {
-  return gLauncherStub->startApplication(application);
-}
-
-bool Launcher::startMApplication(const QString &serviceName) {
-  return gLauncherStub->startMApplication(serviceName);
-}
-
 void Launcher::updatePagesFromDataStore() {
   gLauncherStub->updatePagesFromDataStore();
 }
@@ -152,6 +134,10 @@
   return gLauncherStub->panToPage(fileEntryPath);
 }
 
+void Launcher::setFirstPage() {
+  gLauncherStub->setFirstPage();
+}
+
 void Launcher::updateLauncherButton(const QString &fileEntryPath) {
   gLauncherStub->updateLauncherButton(fileEntryPath);
 }
--- tests/stubs/launcheraction_stub.h
+++ tests/stubs/launcheraction_stub.h
+#include "launcheraction.h"
+#include <stubbase.h>
+
+// 1. DECLARE STUB
+class LauncherActionStub : public StubBase {
+    public:
+        virtual void LauncherActionConstructor();
+        virtual void LauncherActionConstructor(const QString& desktopEntry);
+};
+
+// 2. IMPLEMENT STUB
+void LauncherActionStub::LauncherActionConstructor() {
+}
+
+void LauncherActionStub::LauncherActionConstructor(const QString& desktopEntry) {
+    Q_UNUSED(desktopEntry);
+}
+
+// 3. CREATE A STUB INTERFACE
+LauncherActionStub gDefaultLauncherActionStub;
+LauncherActionStub* gLauncherActionStub = &gDefaultLauncherActionStub;
+
+// 4. CREATE A PROXY WHICH CALLS THE STUB
+LauncherAction::LauncherAction() {
+    gLauncherActionStub->LauncherActionConstructor();
+}
+
+LauncherAction::LauncherAction(const QString& desktopEntry) {
+    gLauncherActionStub->LauncherActionConstructor(desktopEntry);
+}
+
+bool operator!=(const LauncherAction &a, const LauncherAction &b)
+{
+    Q_UNUSED(a);
+    Q_UNUSED(b);
+    return true;
+}
--- tests/stubs/launcherbutton_stub.h
+++ tests/stubs/launcherbutton_stub.h
@@ -12,15 +12,20 @@
   virtual void LauncherButtonConstructor(MWidget *parent);
   virtual void LauncherButtonConstructor(const QString &entry, MWidget *parent);
   virtual void LauncherButtonDestructor();
-  virtual void setTargetType(const QString &type);
-  virtual QString targetType() const;
-  virtual void setTarget(const QString &target);
-  virtual QString target() const;
+  virtual void setAction(const LauncherAction &action);
+  virtual LauncherAction action() const;
   virtual QString desktopEntry() const;
   virtual void launch();
   virtual void updateFromDesktopEntry(const QString &entry);
+  virtual void retranslateUi();
+  virtual bool isInProgress() const;
+  virtual void setProgressIndicatorTimeout(int timeout);
+  virtual void hideProgressIndicator();
+  virtual void hideProgressIndicatorIfObscured(const QList<WindowInfo> &windowList);
+  virtual void init();
 }; 
 
+
 // 2. IMPLEMENT STUB
 void LauncherButtonStub::LauncherButtonConstructor(MWidget *parent) {
   Q_UNUSED(parent);
@@ -32,28 +37,18 @@
 
 }
 void LauncherButtonStub::LauncherButtonDestructor() {
-
-}
-void LauncherButtonStub::setTargetType(const QString &type) {
-  QList<ParameterBase*> params;
-  params.append( new Parameter<QString>(type));
-  stubMethodEntered("setTargetType",params);
+  stubMethodEntered("~LauncherButton");
 }
 
-QString LauncherButtonStub::targetType() const {
-  stubMethodEntered("targetType");
-  return stubReturnValue<QString>("targetType");
-}
-
-void LauncherButtonStub::setTarget(const QString &target) {
+void LauncherButtonStub::setAction(const LauncherAction &action) {
   QList<ParameterBase*> params;
-  params.append( new Parameter<QString >(target));
+  params.append( new Parameter<LauncherAction >(action));
   stubMethodEntered("setTarget",params);
 }
 
-QString LauncherButtonStub::target() const {
-  stubMethodEntered("target");
-  return stubReturnValue<QString>("target");
+LauncherAction LauncherButtonStub::action() const {
+  stubMethodEntered("action");
+  return stubReturnValue<LauncherAction>("action");
 }
 
 QString LauncherButtonStub::desktopEntry() const {
@@ -71,6 +66,41 @@
   stubMethodEntered("updateFromDesktopEntry",params);
 }
 
+void LauncherButtonStub::retranslateUi()
+{
+  stubMethodEntered("retranslateUi");
+}
+
+bool LauncherButtonStub::isInProgress() const
+{
+  stubMethodEntered("isInProgress");
+  return stubReturnValue<bool>("isInProgress");
+}
+
+void LauncherButtonStub::setProgressIndicatorTimeout(int timeout)
+{
+  QList<ParameterBase*> params;
+  params.append( new Parameter<int>(timeout));
+  stubMethodEntered("setProgressIndicatorTimeout",params);
+}
+
+void LauncherButtonStub::hideProgressIndicator()
+{
+  stubMethodEntered("hideProgressIndicator");
+}
+
+void LauncherButtonStub::hideProgressIndicatorIfObscured(const QList<WindowInfo> &windowList)
+{
+  QList<ParameterBase*> params;
+  params.append( new Parameter<QList<WindowInfo> >(windowList));
+  stubMethodEntered("hideProgressIndicatorIfObscured",params);
+}
+
+void LauncherButtonStub::init()
+{
+  stubMethodEntered("init");
+}
+
 
 // 3. CREATE A STUB INSTANCE
 LauncherButtonStub gDefaultLauncherButtonStub;
@@ -90,20 +120,12 @@
   gLauncherButtonStub->LauncherButtonDestructor();
 }
 
-void LauncherButton::setTargetType(const QString &type) {
-  gLauncherButtonStub->setTargetType(type);
+void LauncherButton::setAction(const LauncherAction &action) {
+  gLauncherButtonStub->setAction(action);
 }
 
-QString LauncherButton::targetType() const {
-  return gLauncherButtonStub->targetType();
-}
-
-void LauncherButton::setTarget(const QString &target) {
-  gLauncherButtonStub->setTarget(target);
-}
-
-QString LauncherButton::target() const {
-  return gLauncherButtonStub->target();
+LauncherAction LauncherButton::action() const {
+  return gLauncherButtonStub->action();
 }
 
 QString LauncherButton::desktopEntry() const {
@@ -118,4 +140,34 @@
     gLauncherButtonStub->updateFromDesktopEntry(entry);
 }
 
+void LauncherButton::retranslateUi()
+{
+    gLauncherButtonStub->retranslateUi();
+}
+
+bool LauncherButton::isInProgress() const
+{
+    return gLauncherButtonStub->isInProgress();
+}
+
+void LauncherButton::setProgressIndicatorTimeout(int timeout)
+{
+    gLauncherButtonStub->setProgressIndicatorTimeout(timeout);
+}
+
+void LauncherButton::hideProgressIndicator()
+{
+    gLauncherButtonStub->hideProgressIndicator();
+}
+
+void LauncherButton::hideProgressIndicatorIfObscured(const QList<WindowInfo> &windowList)
+{
+    gLauncherButtonStub->hideProgressIndicatorIfObscured(windowList);
+}
+
+void LauncherButton::init()
+{
+    gLauncherButtonStub->init();
+}
+
 #endif
--- tests/stubs/mockdatastore.h
+++ tests/stubs/mockdatastore.h
@@ -73,6 +73,7 @@
 void MockDataStore::remove(const QString &key)
 {
     values.remove(key);
+    emit valueChanged(key, QVariant());
 }
 
 void MockDataStore::clear()
--- tests/stubs/switcher_stub.h
+++ tests/stubs/switcher_stub.h
@@ -28,11 +28,12 @@
 public:
     virtual void switcherConstructor(MWidget *parent = NULL);
     virtual void switcherDestructor();
-    virtual void windowListUpdated(const QList<WindowInfo> &windowList);
+    virtual void updateWindowList(const QList<WindowInfo> &windowList);
     virtual void windowToFront(Window window);
     virtual void closeWindow(Window window);
-    virtual void viewportSizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos);
     virtual void changeWindowTitle(Window window,  const QString &title);
+    virtual void updateButtons();
+    virtual void scheduleUpdate();
 };
 
 void SwitcherStub::switcherConstructor(MWidget *parent)
@@ -47,11 +48,11 @@
     stubMethodEntered("switcherDestructor");
 }
 
-void SwitcherStub::windowListUpdated(const QList<WindowInfo> &windowList)
+void SwitcherStub::updateWindowList(const QList<WindowInfo> &windowList)
 {
     QList<ParameterBase *> params;
     params.append(new Parameter<QList<WindowInfo> >(windowList));
-    stubMethodEntered("windowListUpdated", params);
+    stubMethodEntered("updateWindowList", params);
 }
 
 void SwitcherStub::windowToFront(Window window)
@@ -68,15 +69,6 @@
     stubMethodEntered("closeWindow", params);
 }
 
-void SwitcherStub::viewportSizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos)
-{
-    QList<ParameterBase *> params;
-    params.append(new Parameter<QSizeF>(viewportSize));
-    params.append(new Parameter<QRectF>(pannedRange));
-    params.append(new Parameter<QPointF>(pannedPos));
-    stubMethodEntered("viewportSizePosChanged", params);
-}
-
 void SwitcherStub::changeWindowTitle(Window window,  const QString &title)
 {
     QList<ParameterBase *> params;
@@ -85,6 +77,16 @@
     stubMethodEntered("changeWindowTitle", params);
 }
 
+void SwitcherStub::updateButtons()
+{
+    stubMethodEntered("updateButtons");
+}
+
+void SwitcherStub::scheduleUpdate()
+{
+    stubMethodEntered("scheduleUpdate");
+}
+
 SwitcherStub gDefaultSwitcherStub;
 SwitcherStub *gSwitcherStub = &gDefaultSwitcherStub;
 
@@ -98,9 +100,9 @@
     gSwitcherStub->switcherDestructor();
 }
 
-void Switcher::windowListUpdated(const QList<WindowInfo> &windowList)
+void Switcher::updateWindowList(const QList<WindowInfo> &windowList)
 {
-    gSwitcherStub->windowListUpdated(windowList);
+    gSwitcherStub->updateWindowList(windowList);
 }
 
 void Switcher::windowToFront(Window window)
@@ -113,14 +115,19 @@
     gSwitcherStub->closeWindow(window);
 }
 
-void Switcher::viewportSizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos)
+void Switcher::changeWindowTitle(Window window,  const QString &title)
 {
-    gSwitcherStub->viewportSizePosChanged(viewportSize, pannedRange, pannedPos);
+    gSwitcherStub->changeWindowTitle(window, title);
 }
 
-void Switcher::changeWindowTitle(Window window,  const QString &title)
+void Switcher::updateButtons()
 {
-    gSwitcherStub->changeWindowTitle(window, title);
+    gSwitcherStub->updateButtons();
+}
+
+void Switcher::scheduleUpdate()
+{
+    gSwitcherStub->scheduleUpdate();
 }
 
 #endif
--- tests/stubs/windowinfo_stub.h
+++ tests/stubs/windowinfo_stub.h
@@ -22,33 +22,47 @@
 #include "windowinfo.h"
 #include <stubbase.h>
 
+Atom WindowInfo::TypeAtom;
+Atom WindowInfo::StateAtom;
+Atom WindowInfo::NormalAtom;
+Atom WindowInfo::DesktopAtom;
+Atom WindowInfo::NotificationAtom;
+Atom WindowInfo::DialogAtom;
+Atom WindowInfo::CallAtom;
+Atom WindowInfo::DockAtom;
+Atom WindowInfo::MenuAtom;
+Atom WindowInfo::SkipTaskbarAtom;
+Atom WindowInfo::NameAtom;
+
 
 // 1. DECLARE STUB
 // FIXME - stubgen is not yet finished
 class WindowInfoStub : public StubBase
 {
 public:
-    virtual void WindowInfoConstructor(QString &title, Window window, XWindowAttributes windowAttributes, Pixmap icon, WindowInfo::WindowPriority priority);
+    virtual void WindowInfoConstructor(Window window);
+    virtual void WindowInfoConstructor();
     virtual void WindowInfoDestructor();
     virtual const QString &title() const;
+    virtual QList<Atom> types() const;
+    virtual QList<Atom> states() const;
     virtual Window window() const;
-    virtual XWindowAttributes windowAttributes() const;
-    virtual Pixmap icon() const;
-    QString _title ;
-    Window _window ;
-    XWindowAttributes _attributes ;
-    Pixmap _pixmap ;
+    virtual bool updateWindowTitle();
+    virtual void updateWindowProperties();
+    QString _title;
+    Window _window;
 };
 
 // 2. IMPLEMENT STUB
-void WindowInfoStub::WindowInfoConstructor(QString &title, Window window, XWindowAttributes windowAttributes, Pixmap icon, WindowInfo::WindowPriority priority)
+void WindowInfoStub::WindowInfoConstructor(Window window)
 {
-    Q_UNUSED(title);
     Q_UNUSED(window);
-    Q_UNUSED(windowAttributes);
-    Q_UNUSED(icon);
-    Q_UNUSED(priority);
 }
+
+void WindowInfoStub::WindowInfoConstructor()
+{
+}
+
 void WindowInfoStub::WindowInfoDestructor()
 {
 
@@ -65,19 +79,28 @@
     return stubReturnValue<Window>("window");
 }
 
-XWindowAttributes WindowInfoStub::windowAttributes() const
+QList<Atom> WindowInfoStub::types() const
 {
-    stubMethodEntered("windowAttributes");
-    return stubReturnValue<XWindowAttributes>("windowAttributes");
+    stubMethodEntered("types");
+    return stubReturnValue<QList<Atom> >("types");
 }
 
-Pixmap WindowInfoStub::icon() const
+QList<Atom> WindowInfoStub::states() const
 {
-    stubMethodEntered("icon");
-    return stubReturnValue<Pixmap>("icon");
+    stubMethodEntered("states");
+    return stubReturnValue<QList<Atom> >("states");
 }
 
-
+bool WindowInfoStub::updateWindowTitle()
+{
+    stubMethodEntered("updateWindowTitle");
+    return stubReturnValue<bool>("updateWindowTitle");
+}
+    
+void WindowInfoStub::updateWindowProperties()
+{
+    stubMethodEntered("updateWindowProperties");
+}
 
 // 3. CREATE A STUB INSTANCE
 WindowInfoStub gDefaultWindowInfoStub;
@@ -85,9 +108,14 @@
 
 
 // 4. CREATE A PROXY WHICH CALLS THE STUB
-WindowInfo::WindowInfo(QString &title, Window window, XWindowAttributes windowAttributes, Pixmap icon, WindowInfo::WindowPriority priority)
+WindowInfo::WindowInfo(Window window)
 {
-    gWindowInfoStub->WindowInfoConstructor(title, window, windowAttributes, icon, priority);
+    gWindowInfoStub->WindowInfoConstructor(window);
+}
+
+WindowInfo::WindowInfo()
+{
+    gWindowInfoStub->WindowInfoConstructor();
 }
 
 WindowInfo::~WindowInfo()
@@ -105,15 +133,29 @@
     return gWindowInfoStub->window();
 }
 
-XWindowAttributes WindowInfo::windowAttributes() const
+QList<Atom> WindowInfo::types() const
 {
-    return gWindowInfoStub->windowAttributes();
+    return gWindowInfoStub->types();
 }
 
-Pixmap WindowInfo::icon() const
+QList<Atom> WindowInfo::states() const
 {
-    return gWindowInfoStub->icon();
+    return gWindowInfoStub->states();
 }
 
+bool WindowInfo::updateWindowTitle()
+{
+    return gWindowInfoStub->updateWindowTitle();
+}
+    
+void WindowInfo::updateWindowProperties()
+{
+    gWindowInfoStub->updateWindowProperties();
+}
 
+bool operator==(const WindowInfo &wi1, const WindowInfo &wi2)
+{
+    return wi1.window() == wi2.window();
+}
+    
 #endif
--- tests/stubs/x11wrapper_stub.h
+++ tests/stubs/x11wrapper_stub.h
@@ -34,6 +34,7 @@
     virtual int XGetWindowProperty(Display *display, Window w, Atom property, long long_offset, long long_length, Bool del, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return);
     virtual int XFree(void *data);
     virtual Status XGetWMName(Display *display, Window w, XTextProperty *text_prop_return);
+    virtual Status XGetTextProperty(Display *display, Window w, XTextProperty *text_prop_return, Atom property);
     virtual XWMHints *XGetWMHints(Display *display, Window w);
     virtual int XFreePixmap(Display *display, Pixmap pixmap);
     virtual Pixmap XCompositeNameWindowPixmap(Display *dpy, Window window);
@@ -113,6 +114,17 @@
     return stubReturnValue<Status>("XGetWMName");
 }
 
+Status X11WrapperStub::XGetTextProperty(Display *display, Window w, XTextProperty *text_prop_return, Atom property)
+{
+    QList<ParameterBase *> params;
+    params.append(new Parameter<Display * >(display));
+    params.append(new Parameter<Window >(w));
+    params.append(new Parameter<XTextProperty * >(text_prop_return));
+    params.append(new Parameter<Atom >(property));
+    stubMethodEntered("XGetTextProperty", params);
+    return stubReturnValue<Status>("XGetTextProperty");
+}
+
 XWMHints *X11WrapperStub::XGetWMHints(Display *display, Window w)
 {
     QList<ParameterBase *> params;
@@ -240,6 +252,11 @@
     return gX11WrapperStub->XGetWMName(display, w, text_prop_return);
 }
 
+Status X11Wrapper::XGetTextProperty(Display *display, Window w, XTextProperty *text_prop_return, Atom property)
+{
+    return gX11WrapperStub->XGetTextProperty(display, w, text_prop_return, property);
+}
+
 XWMHints *X11Wrapper::XGetWMHints(Display *display, Window w)
 {
     return gX11WrapperStub->XGetWMHints(display, w);
--- tests/tests.pro
+++ tests/tests.pro
@@ -1,7 +1,5 @@
 TEMPLATE = subdirs
 SUBDIRS = \
-    ut_appletspace \
-    ut_appletspaceview \
     ut_desktop \
     ut_desktopview \
     ut_home \
@@ -9,6 +7,7 @@
     ut_homescreenservice \
     ut_launcher \
     ut_launcherbutton \
+    ut_launcherbuttonview \
     ut_launcherdatastore \
     ut_launcherpage \
     ut_launcherpageview \
@@ -25,7 +24,6 @@
     ut_switcherbuttonview \
     ut_switcherview \
     ut_windowinfo \
-    ut_x11helper \
     ut_pagepositionindicatorview \
     ut_test
 
--- tests/ut_appletspace
+++ tests/ut_appletspace
-(directory)
--- tests/ut_appletspace/ut_appletspace.cpp
+++ tests/ut_appletspace/ut_appletspace.cpp
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#include <MApplication>
-#include "ut_appletspace.h"
-#include "appletspace.h"
-
-void Ut_AppletSpace::initTestCase()
-{
-}
-
-void Ut_AppletSpace::cleanupTestCase()
-{
-}
-
-void Ut_AppletSpace::init()
-{
-    m_subject = new AppletSpace();
-}
-
-void Ut_AppletSpace::cleanup()
-{
-    delete m_subject;
-}
-
-void Ut_AppletSpace::testEnabled()
-{
-    // Test that close button visibility follows enabledness
-    m_subject->setEnabled(true);
-    QCOMPARE(m_subject->model()->closeButtonVisible(), true);
-
-    m_subject->setEnabled(false);
-    QCOMPARE(m_subject->model()->closeButtonVisible(), false);
-}
-
-QTEST_APPLESS_MAIN(Ut_AppletSpace)
--- tests/ut_appletspace/ut_appletspace.h
+++ tests/ut_appletspace/ut_appletspace.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef UT_APPLETSPACE_H
-#define UT_APPLETSPACE_H
-
-#include <QtTest/QtTest>
-#include <QObject>
-
-class AppletSpace;
-
-class Ut_AppletSpace : public QObject
-{
-    Q_OBJECT
-
-private slots:
-    // Called before the first testfunction is executed
-    void initTestCase();
-    // Called after the last testfunction was executed
-    void cleanupTestCase();
-    // Called before each testfunction is executed
-    void init();
-    // Called after every testfunction
-    void cleanup();
-
-    // Test cases
-    void testEnabled();
-private:
-    // The object being tested
-    AppletSpace *m_subject;
-};
-
-#endif
--- tests/ut_appletspace/ut_appletspace.pro
+++ tests/ut_appletspace/ut_appletspace.pro
-include(../common_top.pri)
-TARGET = ut_appletspace
-
-MODEL_HEADERS += $$SRCDIR/appletspacemodel.h \
-
-# unit test and unit
-SOURCES += \
-    ut_appletspace.cpp \
-    $$SRCDIR/appletspace.cpp
-
-# base classes
-SOURCES += \
-
-
-# unit test and unit
-HEADERS += \
-    ut_appletspace.h \
-    $$SRCDIR/appletspace.h \
-    $$SRCDIR/appletspacemodel.h \
-
-# base classes
-HEADERS += \
-
-
-# service classes
-HEADERS += \
-
-
-include(../common_bot.pri)
--- tests/ut_desktopview/ut_desktopview.cpp
+++ tests/ut_desktopview/ut_desktopview.cpp
@@ -16,7 +16,6 @@
 ** of this file.
 **
 ****************************************************************************/
-
 #include <MApplication>
 #include <MApplicationWindow>
 #include <QPaintEngine>
@@ -26,7 +25,7 @@
 #include <MScene>
 #include <MDeviceProfile>
 #include <MPannableViewport>
-#include <MModalSceneWindow>
+#include <MSceneWindow>
 
 #include "ut_desktopview.h"
 #include "desktopview.h"
@@ -35,12 +34,169 @@
 #include "quicklaunchbar_stub.h"
 #include "launcher_stub.h"
 #include "launcherdatastore_stub.h"
-#include "windowinfo_stub.h"
 #include "homeapplication_stub.h"
 #include "mainwindow_stub.h"
+#include "mwindow_stub.h"
+#include "mscenemanager_stub.h"
 #include <QDBusConnection>
-#include "appletspace_stub.h"
+#include "x11wrapper.h"
+
+#define ATOM_TYPE_NORMAL 1
+#define ATOM_TYPE_NOTIFICATION 2
+#define ATOM_TYPE_MENU 3
+#define ATOM_TYPE_DIALOG 4
+
+// X11Wrapper Stubs
+int X11Wrapper::XSelectInput(Display *, Window , long)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWindowAttributes(Display *, Window, XWindowAttributes *)
+{
+    return 0;
+}
+
+Atom X11Wrapper::XInternAtom(Display *, const char *atom_name, Bool)
+{
+#define ATOM_TYPE_NORMAL 1
+#define ATOM_TYPE_NOTIFICATION 2
+#define ATOM_TYPE_MENU 3
+#define ATOM_TYPE_DIALOG 4
+#define ATOM_TYPE_DESKTOP 5
+#define ATOM_TYPE_DEFAULT 6
+
+    if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
+        return ATOM_TYPE_NORMAL;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NOTIFICATION") == 0) {
+        return ATOM_TYPE_NOTIFICATION;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_MENU") == 0) {
+        return ATOM_TYPE_MENU;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
+        return ATOM_TYPE_DIALOG;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DESKTOP") == 0) {
+        return ATOM_TYPE_DESKTOP;
+    } else {
+        return ATOM_TYPE_DEFAULT;
+    }
+}
+
+int X11Wrapper::XGetWindowProperty(Display *dpy, Window w, Atom property, long long_offset, long long_length, Bool del, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return)
+{
+    Q_UNUSED(dpy);
+    Q_UNUSED(property);
+    Q_UNUSED(long_offset);
+    Q_UNUSED(long_length);
+    Q_UNUSED(del);
+    Q_UNUSED(req_type);
+    Q_UNUSED(actual_type_return);
+    Q_UNUSED(actual_format_return);
+    Q_UNUSED(bytes_after_return);
+
+    if (w == ATOM_TYPE_NORMAL) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_NORMAL;
+        return Success;
+    } else if (w == ATOM_TYPE_NOTIFICATION) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_NOTIFICATION;
+        return Success;
+    } else if (w == ATOM_TYPE_MENU) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_MENU;
+        return Success;
+    } else if (w == ATOM_TYPE_DIALOG) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_DIALOG;
+        return Success;
+    } else if (w == ATOM_TYPE_DEFAULT) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_DEFAULT;
+        return Success;
+    } else {
+        return BadAtom;
+    }
+}
+
+int X11Wrapper::XFree(void *)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWMName(Display *, Window, XTextProperty *)
+{
+    return -1;
+}
+
+Status X11Wrapper::XGetTextProperty(Display *, Window , XTextProperty *text_prop_return, Atom)
+{
+    QString textValue("Title");
+    std::string::size_type strSize = textValue.toStdString().length();
+    text_prop_return->value = new unsigned char[strSize + 1];
+    strncpy((char *)text_prop_return->value, textValue.toStdString().c_str(), strSize + 1);
+    return 1;
+}
+
+XWMHints *X11Wrapper::XGetWMHints(Display *, Window)
+{
+    return 0;
+}
+
+int X11Wrapper::XFreePixmap(Display *, Pixmap)
+{
+    return 0;
+}
+
+Pixmap X11Wrapper::XCompositeNameWindowPixmap(Display *, Window)
+{
+    return 0;
+}
+
+Damage X11Wrapper::XDamageCreate(Display *, Drawable, int)
+{
+    return 0;
+}
+
+void X11Wrapper::XDamageDestroy(Display *, Damage)
+{
 
+}
+
+int X11Wrapper::XSync(Display *, Bool)
+{
+    return 0;
+}
+
+XErrorHandler X11Wrapper::XSetErrorHandler(XErrorHandler)
+{
+    return 0;
+}
+
+int X11Wrapper::XChangeProperty(Display *, Window, Atom, Atom, int, int, unsigned char *, int)
+{
+    return 0;
+}
+
+Status X11Wrapper::XSendEvent(Display *, Window, Bool, long, XEvent *)
+{
+    return 0;
+}
+
+
+WId QWidget::winId() const
+{
+    return 0xfeedbeef;
+}
 
 // QWidget stubs
 bool windowActivated = false;
@@ -56,20 +212,25 @@
      windowRaised = true;
 }
 
-// MSceneManager stubs
-void MSceneManager::appearSceneWindow(MSceneWindow *window, MSceneWindow::DeletionPolicy)
+// QGraphicsItem stubs
+void QGraphicsItem::setZValue(qreal)
 {
-    window->show();
 }
 
-void MSceneManager::disappearSceneWindow(MSceneWindow *window)
+static bool gQGraphicsItemIsVisible = true;
+bool QGraphicsItem::isVisible() const
 {
-    window->hide();
+    if (dynamic_cast<const Launcher*>(this) || dynamic_cast<const MSceneWindow*>(this)) {
+        return gQGraphicsItemIsVisible;
+    }
+    return false;
 }
 
-// QGraphicsItem stubs
-void QGraphicsItem::setZValue(qreal)
+void MWidget::setVisible(bool visible)
 {
+    if (dynamic_cast<const Launcher*>(this)) {
+        gQGraphicsItemIsVisible = visible;
+    }
 }
 
 // QDBusConnection stubs
@@ -109,6 +270,12 @@
 {
 }
 
+bool extensionDefocused;
+void TestDesktopBackgroundExtension::setDefocused(bool defocused)
+{
+    extensionDefocused = defocused;
+}
+
 void TestDesktopBackgroundExtension::drawBackground(QPainter *, const QRectF &boundingRect) const
 {
     this->boundingRect = boundingRect;
@@ -139,7 +306,6 @@
 void Ut_DesktopView::cleanupTestCase()
 {
     delete mainWindow;
-
     // Destroy the MApplication
     delete app;
 }
@@ -150,11 +316,18 @@
     desktopView = new TestDesktopView(desktop);
     desktop->setView(desktopView);
     desktopView->modifiableStyle()->setDesktopBackgroundImage(backgroundImage);
-    connect(this, SIGNAL(launcherButtonClicked()), desktopView, SLOT(toggleLauncher()));
-
+    connect(this, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)),
+            desktopView, SLOT(updateLauncherVisiblity(const QList<WindowInfo> &)));
+    connect(this, SIGNAL(windowListUpdated(const QList<WindowInfo> &)),
+            desktopView, SLOT(setSwitcherHasContent(const QList<WindowInfo> &)));
     // For QWidget activateWindow() and raise() stubs
     windowRaised = false;
     windowActivated = false;
+    gQGraphicsItemIsVisible = false;
+    extensionDefocused = false;
+
+    gMSceneManagerStub->stubReset();
+    gLauncherStub->stubReset();
 }
 
 void Ut_DesktopView::cleanup()
@@ -162,6 +335,18 @@
     delete desktop;
 }
 
+void Ut_DesktopView::testToggleLauncher()
+{
+    gQGraphicsItemIsVisible = false;
+    desktopView->toggleLauncher();
+    QCOMPARE(1, gLauncherStub->stubCallCount("setFirstPage"));
+    verifyAppearDisappear(desktopView->launcherWindow, desktopView->switcherWindow);
+
+    gQGraphicsItemIsVisible = true;
+    desktopView->toggleLauncher();
+    verifyAppearDisappear(desktopView->switcherWindow, desktopView->launcherWindow);
+}
+
 void Ut_DesktopView::testBoundingRectAndDrawBackground()
 {
     // Add two extensions to the registered list of extensions
@@ -178,72 +363,127 @@
     QCOMPARE(extension2.boundingRect, br);
 }
 
-void Ut_DesktopView::testShowingHidingLauncher()
+void Ut_DesktopView::testUpdatingLauncherVisibilityWithApplicationOnTop()
 {
-    QCOMPARE(desktopView->launcherWindow->isVisible(), false);
+    verifyLauncherVisibility(1, false);
+}
 
-    // Show launcher
-    emit launcherButtonClicked();
-    QCOMPARE(desktopView->launcherWindow->isVisible(), true);
-    QCOMPARE(desktopView->launcher->isEnabled(), true);
+void Ut_DesktopView::testUpdatingLauncherVisibilityWithNotificationOnTop()
+{
+    verifyLauncherVisibility(2, true);
+}
 
-    // Hide launcher
-    emit launcherButtonClicked();
-    QCOMPARE(desktopView->launcherWindow->isVisible(), false);
-    QCOMPARE(desktopView->launcher->isEnabled(), false);
+void Ut_DesktopView::testUpdatingLauncherVisibilityWithStatusIndicatorMenuOnTop()
+{
+    verifyLauncherVisibility(3, true);
 }
 
+void Ut_DesktopView::testUpdatingLauncherVisibilityWithDialogOnTop()
+{
+    verifyLauncherVisibility(4, true);
+}
+
+void Ut_DesktopView::testUpdatingLauncherVisibilityWithDesktopOnTop()
+{
+    verifyLauncherVisibility(0xfeedbeef, true);
+}
+
+void Ut_DesktopView::verifyAppearDisappear(MSceneWindow *appear, MSceneWindow *disappear)
+{
+    QCOMPARE(gMSceneManagerStub->stubCallCount("appearSceneWindow"), 1);
+    QCOMPARE(gMSceneManagerStub->stubCallCount("disappearSceneWindow"), 1);
+    QCOMPARE(gMSceneManagerStub->stubLastCallTo("appearSceneWindow").parameter<MSceneWindow *>(0), appear);
+    QCOMPARE(gMSceneManagerStub->stubLastCallTo("disappearSceneWindow").parameter<MSceneWindow *>(0), disappear);
+    gMSceneManagerStub->stubReset();
+}
+
+void Ut_DesktopView::verifyLauncherVisibility(int topMostWindowId, bool shouldBeVisible)
+{
+    desktopView->showLauncher();
+
+    verifyAppearDisappear(desktopView->launcherWindow, desktopView->switcherWindow);
+
+    gQGraphicsItemIsVisible = true;
+    QList<WindowInfo> windowList;
+    windowList.append(WindowInfo(topMostWindowId));
+    emit windowStackingOrderChanged(windowList);
+
+    if (!shouldBeVisible) {
+        verifyAppearDisappear(desktopView->switcherWindow, desktopView->launcherWindow);
+    }
+}
 
 void Ut_DesktopView::testShowLauncherAndPanToPageWithCorrectDesktopFile()
 {
     gLauncherStub->stubSetReturnValue("panToPage", 1);
+    desktopView->hideLauncher();
 
-    desktopView->launcher->setEnabled(false);
-
-    QCOMPARE(desktopView->launcherWindow->isVisible(), false);
-    QCOMPARE(desktopView->launcher->isEnabled(), false);
+    verifyAppearDisappear(desktopView->switcherWindow, desktopView->launcherWindow);
 
     desktopView->showLauncherAndPanToPage("correctFileName");
+    gQGraphicsItemIsVisible = true;
 
     QCOMPARE(windowActivated, true);
     QCOMPARE(windowRaised, true);
-    QCOMPARE(desktopView->launcherWindow->isVisible(), true);
-    QCOMPARE(desktopView->launcher->isEnabled(), true);
+
+    verifyAppearDisappear(desktopView->launcherWindow, desktopView->switcherWindow);
 }
 
 void Ut_DesktopView::testShowLauncherAndPanToPageWithBadDesktopFile()
 {
     gLauncherStub->stubSetReturnValue("panToPage", -1);
 
-    desktopView->launcher->setEnabled(false);
+    desktopView->launcher->setVisible(false);
 
     QCOMPARE(desktopView->launcherWindow->isVisible(), false);
-    QCOMPARE(desktopView->launcher->isEnabled(), false);
 
     desktopView->showLauncherAndPanToPage("badFileName");
 
     QCOMPARE(windowActivated, false);
     QCOMPARE(windowRaised, false);
     QCOMPARE(desktopView->launcherWindow->isVisible(), false);
-    QCOMPARE(desktopView->launcher->isEnabled(), false);
 }
 
 void Ut_DesktopView::testShowLauncherAndPanToPageWithEmptyDesktopFile()
 {
     gLauncherStub->stubSetReturnValue("panToPage", -1);
 
-    desktopView->launcher->setEnabled(false);
-
     QCOMPARE(desktopView->launcherWindow->isVisible(), false);
-    QCOMPARE(desktopView->launcher->isEnabled(), false);
 
-    //emit focusToLauncherAppRequested("asd");
     desktopView->showLauncherAndPanToPage("");
+    gQGraphicsItemIsVisible = true;
 
     QCOMPARE(windowActivated, true);
     QCOMPARE(windowRaised, true);
-    QCOMPARE(desktopView->launcherWindow->isVisible(), true);
-    QCOMPARE(desktopView->launcher->isEnabled(), true);
+
+    QCOMPARE(1, gMSceneManagerStub->stubCallCount("appearSceneWindow"));
+}
+
+void Ut_DesktopView::testDefocusing()
+{
+    TestDesktopBackgroundExtension extension;
+    desktopView->addExtension(&extension);
+
+    desktopView->showLauncher();
+    QVERIFY(extensionDefocused);
+
+    desktopView->hideLauncher();
+    QVERIFY(!extensionDefocused);
+
+    QList<WindowInfo> windowList;
+    windowList.append(WindowInfo(0));
+    emit windowListUpdated(windowList);
+    QVERIFY(extensionDefocused);
+
+    desktopView->showLauncher();
+    QVERIFY(extensionDefocused);
+
+    windowList.clear();
+    emit windowListUpdated(windowList);
+    QVERIFY(extensionDefocused);
+
+    desktopView->hideLauncher();
+    QVERIFY(!extensionDefocused);
 }
 
 QTEST_APPLESS_MAIN(Ut_DesktopView)
--- tests/ut_desktopview/ut_desktopview.h
+++ tests/ut_desktopview/ut_desktopview.h
@@ -40,6 +40,7 @@
     mutable QRectF boundingRect;
     virtual bool initialize(const QString &);
     virtual void setDesktopInterface(MDesktopInterface &desktopInterface);
+    virtual void setDefocused(bool defocused);
     virtual void drawBackground(QPainter *painter, const QRectF &boundingRect) const;
 };
 
@@ -73,25 +74,36 @@
     // Called after every testfunction
     void cleanup();
 
+    // Test opening launcher to first page
+    void testToggleLauncher();
     // Test bounding rectangle and background drawing
     void testBoundingRectAndDrawBackground();
     // Test showing and hiding launcher
-    void testShowingHidingLauncher();
+    void testUpdatingLauncherVisibilityWithApplicationOnTop();
+    void testUpdatingLauncherVisibilityWithNotificationOnTop();
+    void testUpdatingLauncherVisibilityWithStatusIndicatorMenuOnTop();
+    void testUpdatingLauncherVisibilityWithDialogOnTop();
+    void testUpdatingLauncherVisibilityWithDesktopOnTop();
     // Test showing launcher when showLauncherAndPanToPage is called
     void testShowLauncherAndPanToPageWithCorrectDesktopFile();
     // Test that launcher is not shown when bad desktop file is given
     void testShowLauncherAndPanToPageWithBadDesktopFile();
     // Test show launcher with empty desktop file path given
     void testShowLauncherAndPanToPageWithEmptyDesktopFile();
+    void testDefocusing();
 
 public:
     // The main window
     static MainWindow *mainWindow;
 
 signals:
-    void launcherButtonClicked();
+    void windowStackingOrderChanged(const QList<WindowInfo> &);
+    void windowListUpdated(const QList<WindowInfo> &);
 
 private:
+    void verifyAppearDisappear(MSceneWindow *appear, MSceneWindow *disappear);
+    void verifyLauncherVisibility(int topMostWindowId, bool shouldBeVisible);
+
     // The mapp
     MApplication *app;
     // The object being tested
--- tests/ut_desktopview/ut_desktopview.pro
+++ tests/ut_desktopview/ut_desktopview.pro
@@ -8,7 +8,8 @@
 # unit test and unit
 SOURCES += \
     ut_desktopview.cpp \
-    $$SRCDIR/desktopview.cpp
+    $$SRCDIR/desktopview.cpp \
+    $$SRCDIR/windowinfo.cpp
 
 # base classes
 SOURCES += \
@@ -27,6 +28,7 @@
 
 # service classes
 HEADERS += \
+    $$SRCDIR/windowinfo.h \
     $$SRCDIR/desktop.h \
     $$SRCDIR/desktopmodel.h \
     $$SRCDIR/desktopstyle.h \
@@ -35,7 +37,6 @@
     $$SRCDIR/switcher.h \
     $$SRCDIR/quicklaunchbar.h \
     $$SRCDIR/launcher.h \
-    $$SRCDIR/launcherdatastore.h \
-    $$SRCDIR/appletspace.h
+    $$SRCDIR/launcherdatastore.h
 
 include(../common_bot.pri)
--- tests/ut_home/ut_home.cpp
+++ tests/ut_home/ut_home.cpp
@@ -27,6 +27,7 @@
 #include "homeapplication_stub.h"
 #include "home.h"
 #include "desktop.h"
+#include "windowinfo_stub.h"
 #include "x11wrapper_stub.h"
 
 // X stubs to avoid crashes
--- tests/ut_homeapplication/ut_homeapplication.cpp
+++ tests/ut_homeapplication/ut_homeapplication.cpp
@@ -33,29 +33,42 @@
 #include <signal.h>
 
 #include "x11wrapper.h"
-#include "x11helper.h"
 
 #define ATOM_TYPE 0x00010000
 #define ATOM_TYPE_NORMAL 0x00010001
-#define ATOM_TYPE_DESKTOP 0x00010002
-#define ATOM_TYPE_NOTIFICATION 0x00010003
-#define ATOM_TYPE_DOCK 0x00010004
-#define ATOM_TYPE_CALL 0x00010005
-#define ATOM_TYPE_DIALOG 0x00010006
-#define ATOM_TYPE_MENU 0x00010007
-#define ATOM_TYPE_SOMETHING_ELSE 0x00010008
 #define ATOM_CLIENT_LIST 0x00020000
 #define ATOM_CLIENT_LIST_STACKING 0x00030000
 #define ATOM_CLOSE_WINDOW 0x00040000
-#define ATOM_WM_STATE_SKIP_TASKBAR 0x00050001
 
 #define NET_WM_STATE 0x00060001
 #define ATOM_NET_WM_NAME 0x00070001
 #define ATOM_WM_NAME 0x00080001
-#define WINDOW_ATTRIBUTE_TEST_WINDOWS 16
-#define WINDOW_TYPE_TEST_WINDOWS 12
-#define NET_WM_STATE_WINDOWS 1
-#define NUMBER_OF_WINDOWS (WINDOW_ATTRIBUTE_TEST_WINDOWS + WINDOW_TYPE_TEST_WINDOWS + NET_WM_STATE_WINDOWS)
+
+#define INVALID_WINDOWS 16
+#define APPLICATION_WINDOWS 2
+#define NON_APPLICATION_WINDOWS 5
+#define VALID_WINDOWS (NON_APPLICATION_WINDOWS + APPLICATION_WINDOWS)
+
+#define NUMBER_OF_WINDOWS (INVALID_WINDOWS + VALID_WINDOWS)
+
+#define ATOM_TYPE_DESKTOP 100
+#define ATOM_TYPE_NOTIFICATION 101
+#define ATOM_TYPE_DIALOG 102
+#define ATOM_TYPE_DOCK 103
+#define ATOM_TYPE_MENU 104
+#define ATOM_STATE_SKIP_TASKBAR 105
+
+#define ATOM_TYPE_INVALID 666
+
+WId QWidget::winId() const
+{
+    return 0xbadf00d;
+}
+
+static QMap<Window, QVector<Atom> > g_windowTypeMap;
+static QMap<Window, QVector<Atom> > g_windowStateMap;
+static QVector<Window> g_windows;
+static bool g_windowName;
 
 // QCoreApplication stubs to avoid crashing in processEvents()
 QStringList QCoreApplication::arguments()
@@ -72,37 +85,30 @@
 {
     if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE") == 0) {
         return ATOM_TYPE;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
-        return ATOM_TYPE_NORMAL;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DESKTOP") == 0) {
-        return ATOM_TYPE_DESKTOP;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NOTIFICATION") == 0) {
-        return ATOM_TYPE_NOTIFICATION;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DOCK") == 0) {
-        return ATOM_TYPE_DOCK;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_CALL") == 0) {
-        return ATOM_TYPE_CALL;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
-        return ATOM_TYPE_DIALOG;
-    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_MENU") == 0) {
-        return ATOM_TYPE_MENU;
-    } else if (strcmp(atom_name, "_NET_CLIENT_LIST") == 0) {
-        return ATOM_CLIENT_LIST;
     } else if (strcmp(atom_name, "_NET_CLIENT_LIST_STACKING") == 0) {
         return ATOM_CLIENT_LIST_STACKING;
     } else if (strcmp(atom_name, "_NET_CLOSE_WINDOW") == 0) {
         return ATOM_CLOSE_WINDOW;
-    } else if (strcmp(atom_name, "_NET_WM_STATE_SKIP_TASKBAR") == 0) {
-        return ATOM_WM_STATE_SKIP_TASKBAR;
     } else if (strcmp(atom_name, "_NET_WM_STATE") == 0) {
         return NET_WM_STATE;
     } else if (strcmp(atom_name, "_NET_WM_NAME") == 0) {
         return ATOM_NET_WM_NAME;
     } else if (strcmp(atom_name, "WM_NAME") == 0) {
         return ATOM_WM_NAME;
+    } else if (strcmp(atom_name, "_NET_WM_STATE_SKIP_TASKBAR") == 0) {
+        return ATOM_STATE_SKIP_TASKBAR;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DESKTOP") == 0) {
+        return ATOM_TYPE_DESKTOP;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NOTIFICATION") == 0) {
+        return ATOM_TYPE_NOTIFICATION;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
+        return ATOM_TYPE_DIALOG;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_MENU") == 0) {
+        return  ATOM_TYPE_MENU;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DOCK") == 0) {
+        return ATOM_TYPE_DOCK;
     }
-
-    return 0;
+    return ATOM_TYPE_INVALID;
 }
 
 int X11Wrapper::XSelectInput(Display *, Window window, long mask)
@@ -199,7 +205,7 @@
     Q_UNUSED(actual_format_return);
     Q_UNUSED(bytes_after_return);
 
-    if (property == ATOM_CLIENT_LIST) {
+    if (property == ATOM_CLIENT_LIST_STACKING) {
         if (w != DefaultRootWindow(dpy)) {
             return BadWindow;
         } else {
@@ -207,105 +213,33 @@
             *prop_return = new unsigned char[Ut_HomeApplication::clientListNumberOfWindows * sizeof(Window)];
 
             Window *windows = (Window *) * prop_return;
-            for (int i = 0; i < Ut_HomeApplication::clientListNumberOfWindows; i++)
-                windows[i] = i + 1;
+            for (int w = 0; w < g_windows.count(); w++) {
+                windows[w] = g_windows[w];
+            }
+            //for (int i = 0; i < Ut_HomeApplication::clientListNumberOfWindows; i++)
+            //windows[i] = i;
             return Success;
         }
     } else if (property == ATOM_TYPE) {
-        Atom *atom;
-
-        switch (w) {
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0):
-            *nitems_return = 0;
-            *prop_return = new unsigned char[0];
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 1):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_DESKTOP;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 2):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NOTIFICATION;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 3):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_DOCK;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 5):
-            *nitems_return = 2;
-            *prop_return = new unsigned char[2 * sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            atom[1] = ATOM_TYPE_DESKTOP;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 6):
-            *nitems_return = 2;
-            *prop_return = new unsigned char[2 * sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            atom[1] = ATOM_TYPE_NOTIFICATION;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 7):
-            *nitems_return = 3;
-            *prop_return = new unsigned char[3 * sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            atom[1] = ATOM_TYPE_DESKTOP;
-            atom[2] = ATOM_TYPE_NOTIFICATION;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 8):
-            *nitems_return = 2;
-            *prop_return = new unsigned char[2 * sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            atom[1] = ATOM_TYPE_SOMETHING_ELSE;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 9):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_CALL;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 10):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_DIALOG;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 11):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_MENU;
-            break;
-        case(WINDOW_ATTRIBUTE_TEST_WINDOWS + WINDOW_TYPE_TEST_WINDOWS):
-            *nitems_return = 1;
-            *prop_return = new unsigned char[sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = NET_WM_STATE;
-            break;
-        default:
-            *nitems_return = 1;
-            *prop_return = new unsigned char[1 * sizeof(Atom)];
-            atom = (Atom *) * prop_return;
-            atom[0] = ATOM_TYPE_NORMAL;
-            break;
+        QVector<Atom> types = g_windowTypeMap[w];
+        *nitems_return = types.count();
+        *prop_return = new unsigned char[*nitems_return * sizeof(Atom)];
+        Atom *atom = (Atom*)*prop_return;
+        for (int i = 0; i < types.count(); i++) {
+            atom[i] = types[i];
+        }
+        return Success;
+    } else if (property == NET_WM_STATE) {
+        QVector<Atom> states = g_windowStateMap[w];
+        *nitems_return = states.count();
+        *prop_return = new unsigned char[*nitems_return * sizeof(Atom)];
+        Atom *atom = (Atom*)*prop_return;
+        for (int i = 0; i < states.count(); i++) {
+            atom[i] = states[i];
         }
         return Success;
-    } else
-        return BadAtom;
+    }
+    return BadAtom;
 }
 
 int X11Wrapper::XFree(void *data)
@@ -316,92 +250,29 @@
     return 0;
 }
 
-Status X11Wrapper::XGetWMName(Display *, Window w, XTextProperty *text_prop_return)
+Status X11Wrapper::XGetWMName(Display *, Window , XTextProperty* )
 {
-    QString textValue;
-
-    switch (w) {
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0):
-        textValue = "plain_x_window";
-        break;
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4):
-        textValue = "Test";
-        break;
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 8):
-        textValue = "Tzzt";
-        break;
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 9):
-        textValue = "Call_ui";
-        break;
-    default:
-        break;
-    }
-
-    if (textValue.isEmpty()) {
-        return 0;
-    } else {
-        std::string::size_type strSize = textValue.toStdString().length();
-        text_prop_return->value = new unsigned char[strSize + 1];
-        strncpy((char *)text_prop_return->value, textValue.toStdString().c_str(), strSize + 1);
-        return 1;
-    }
+    return g_windowName ? 1 : 0;
 }
 
-XWMHints *X11Wrapper::XGetWMHints(Display *, Window w)
+XWMHints *X11Wrapper::XGetWMHints(Display *, Window)
 {
-    XWMHints *wmhints = NULL;
-    switch (w) {
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4):
-        wmhints = (XWMHints *)new unsigned char[sizeof(XWMHints)];
-        wmhints->icon_pixmap = 202;
-        break;
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 8):
-        wmhints = (XWMHints *)new unsigned char[sizeof(XWMHints)];
-        wmhints->icon_pixmap = 303;
-        break;
-    default:
-        break;
-    }
-
-    return wmhints;
+    return NULL;
 }
 
-Status X11Wrapper::XGetTextProperty(Display *, Window w, XTextProperty *text_prop_return, Atom /*property*/)
+Status X11Wrapper::XGetTextProperty(Display *, Window, XTextProperty *text_prop_return, Atom)
 {
-    QString textValue;
-
-    switch (w) {
-    case(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0):
-        textValue = "Window 0 _NET_WM_NAME changed title";
-        break;
-    default:
-        break;
-    }
-
-    if (textValue.isEmpty()) {
-        return 0;
-    } else {
+    if (g_windowName) {
+        QString textValue("title");
         std::string::size_type strSize = textValue.toStdString().length();
         text_prop_return->value = new unsigned char[strSize + 1];
         strncpy((char *)text_prop_return->value, textValue.toStdString().c_str(), strSize + 1);
         return 1;
+    } else {
+        return 0;
     }
 }
 
-bool isSkipTaskbarWindow = false;
-QVector<Atom> X11Helper::getNetWmState(Display *display, Window window)
-{
-    Q_UNUSED(display);
-
-    QVector<Atom> returnValue;
-
-    if (window == WINDOW_ATTRIBUTE_TEST_WINDOWS + WINDOW_TYPE_TEST_WINDOWS + 1 || (isSkipTaskbarWindow && window == WINDOW_ATTRIBUTE_TEST_WINDOWS + 4)) {
-        returnValue.append(ATOM_WM_STATE_SKIP_TASKBAR);
-    }
-
-    return returnValue;
-}
-
 void XSetWMProperties(Display *, Window, XTextProperty *, XTextProperty *, char **, int, XSizeHints *, XWMHints *, XClassHint *)
 {
 }
@@ -502,6 +373,7 @@
 {
 }
 
+
 void Ut_HomeApplication::init()
 {
     validInterfaces.clear();
@@ -509,12 +381,31 @@
     asyncCallMethods.clear();
     asyncCallArguments.clear();
     clientListNumberOfWindows = NUMBER_OF_WINDOWS;
-    isSkipTaskbarWindow = false;
 
     static char *args[] = {(char *) "./ut_homeapplication"};
     static int argc = sizeof(args) / sizeof(char *);
     m_subject = new TestHomeApplication(argc, args);
     visibilityNotifyWindows.clear();
+
+    g_windowName = true;
+    g_windowTypeMap.clear();
+
+    g_windows = QVector<Window>(clientListNumberOfWindows);
+    for (int w = 0; w < clientListNumberOfWindows; w++) {
+        QVector<Atom> types(1);
+        types[0] = ATOM_TYPE_NORMAL;
+        g_windowTypeMap[w] = types;
+
+        g_windows[w] = w;
+    }
+    // Add non-application windows
+    g_windowTypeMap[INVALID_WINDOWS + APPLICATION_WINDOWS + 0][0] = ATOM_TYPE_DESKTOP;
+    g_windowTypeMap[INVALID_WINDOWS + APPLICATION_WINDOWS + 1][0] = ATOM_TYPE_NOTIFICATION;
+    g_windowTypeMap[INVALID_WINDOWS + APPLICATION_WINDOWS + 2][0] = ATOM_TYPE_DIALOG;
+    g_windowTypeMap[INVALID_WINDOWS + APPLICATION_WINDOWS + 3][0] = ATOM_TYPE_DOCK;
+    g_windowTypeMap[INVALID_WINDOWS + APPLICATION_WINDOWS + 4][0] = ATOM_TYPE_MENU;
+
+    g_windowStateMap.clear();
 }
 
 void Ut_HomeApplication::cleanup()
@@ -581,23 +472,16 @@
     connect(m_subject, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), &r, SLOT(windowListUpdated(const QList<WindowInfo> &)));
 
     XEvent event;
-    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", False);
+    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", False);
     event.type = PropertyNotify;
     event.xproperty.window = DefaultRootWindow(QX11Info::display());
+
     QVERIFY(m_subject->testX11EventFilter(&event));
 
     // Make sure the window list change signal was emitted
     QCOMPARE(r.count, 1);
-    // There should be 4 windows in the window list
-    QCOMPARE(r.windowList.count(), 4);
 
-    event.type = PropertyNotify;
-    event.xproperty.window = WINDOW_ATTRIBUTE_TEST_WINDOWS + 4;
-    event.xproperty.atom = NET_WM_STATE;
-    isSkipTaskbarWindow = true;
-    QVERIFY(m_subject->testX11EventFilter(&event));
-    // There should be 3 windows in the window list
-    QCOMPARE(r.windowList.count(), 3);
+    QCOMPARE(r.windowList.count(), APPLICATION_WINDOWS);
 }
 
 void Ut_HomeApplication::testX11EventFilterWithPropertyNotify()
@@ -618,7 +502,7 @@
     event.type = 0;
     QVERIFY(!m_subject->testX11EventFilter(&event));
 
-    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", False);
+    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", False);
     QVERIFY(!m_subject->testX11EventFilter(&event));
 
     event.xproperty.window = 0;
@@ -631,49 +515,28 @@
 
     // Make sure the window list change signal was emitted
     QCOMPARE(r.count, 1);
+    QCOMPARE(r.windowList.count(), APPLICATION_WINDOWS);
 
-    WindowListReceiver stackingReceiver;
-    connect(m_subject, SIGNAL(windowStackingChanged(const QList<WindowInfo> &)),
-            &stackingReceiver, SLOT(windowStackingChanged(const QList<WindowInfo> &)));
-
-    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", False);
+    // Update the state of a window that currently is an application window
+    QVector<Atom> states(1);
+    states[0] = ATOM_STATE_SKIP_TASKBAR;
+    g_windowStateMap[INVALID_WINDOWS] = states;
+    event.xproperty.window = INVALID_WINDOWS;
+    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_WM_STATE", False);
     QVERIFY(m_subject->testX11EventFilter(&event));
-    QCOMPARE(stackingReceiver.stackCount, 1);
+    QCOMPARE(r.count, 2);
+    QCOMPARE(r.windowList.count(), APPLICATION_WINDOWS - 1);
 
-    // There should be 3 windows in the window list and their information should be correct
-    QCOMPARE(r.windowList.count(), 4);
-    QCOMPARE(r.windowList.at(0).title(), QString("plain_x_window"));
-    QCOMPARE(r.windowList.at(0).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0));
-    QCOMPARE(r.windowList.at(0).windowPriority(), WindowInfo::Normal);
-    QCOMPARE(r.windowList.at(1).title(), QString("Test"));
-    QCOMPARE(r.windowList.at(1).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-    QCOMPARE(r.windowList.at(1).windowAttributes().width, 100 + (WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-    QCOMPARE(r.windowList.at(1).windowAttributes().height, 200 + (WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-    QCOMPARE(r.windowList.at(1).windowAttributes().c_class, InputOutput);
-    QVERIFY(r.windowList.at(1).windowAttributes().map_state != IsUnmapped);
-    QCOMPARE(r.windowList.at(1).icon(), (Pixmap)202);
-    QCOMPARE(r.windowList.at(1).windowPriority(), WindowInfo::Normal);
-    QCOMPARE(r.windowList.at(2).title(), QString("Tzzt"));
-    QCOMPARE(r.windowList.at(2).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 8));
-    QCOMPARE(r.windowList.at(2).windowAttributes().width, 100 + (WINDOW_ATTRIBUTE_TEST_WINDOWS + 8));
-    QCOMPARE(r.windowList.at(2).windowAttributes().height, 200 + (WINDOW_ATTRIBUTE_TEST_WINDOWS + 8));
-    QCOMPARE(r.windowList.at(2).windowAttributes().c_class, InputOutput);
-    QCOMPARE(r.windowList.at(2).icon(), (Pixmap)303);
-    QVERIFY(r.windowList.at(2).windowAttributes().map_state != IsUnmapped);
-    QCOMPARE(r.windowList.at(2).windowPriority(), WindowInfo::Normal);
-    QCOMPARE(r.windowList.at(3).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 9));
-    QCOMPARE(r.windowList.at(3).windowPriority(), WindowInfo::Call);
-    QCOMPARE(r.windowList.at(3).title(), QString("Call_ui"));
-
-    // HomeApplication should be interested in the windows' VisibilityNotifys
-    QCOMPARE(visibilityNotifyWindows.count(), 4);
-    QCOMPARE(visibilityNotifyWindows.at(0), r.windowList.at(0).window());
-    QCOMPARE(visibilityNotifyWindows.at(1), r.windowList.at(1).window());
-    QCOMPARE(visibilityNotifyWindows.at(2), r.windowList.at(2).window());
-    QCOMPARE(visibilityNotifyWindows.at(3), r.windowList.at(3).window());
+    // Update the type of a window that currently is an application window
+    g_windowTypeMap[INVALID_WINDOWS + 1][0] = ATOM_TYPE_MENU;
+    event.xproperty.window = INVALID_WINDOWS + 1;
+    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_WM_WINDOW_TYPE", False);
+    QVERIFY(m_subject->testX11EventFilter(&event));
+    QCOMPARE(r.count, 3);
+    QCOMPARE(r.windowList.count(), 0);
 }
 
-void Ut_HomeApplication::testX11EventFilterWithVisibilityNotify()
+/*void Ut_HomeApplication::testX11EventFilterWithVisibilityNotify()
 {
     MainWindow *w = MainWindow::instance(true);
     QList<MWindow *> windowList;
@@ -716,7 +579,7 @@
     QVERIFY(!m_subject->testX11EventFilter(&event));
     QCOMPARE(r.windowList.count(), 1);
     QCOMPARE(gMApplicationStub->stubCallCount("x11EventFilter"), x11EventFilterCallCount + 1);
-}
+}*/
 
 void Ut_HomeApplication::testX11EventFilterWithClientMessage()
 {
@@ -734,114 +597,76 @@
     clientEvent.xclient.message_type = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLOSE_WINDOW", False);
     QVERIFY(!m_subject->testX11EventFilter(&clientEvent));
     clientEvent.type = ClientMessage;
-    clientEvent.xclient.window = WINDOW_ATTRIBUTE_TEST_WINDOWS + 8;
+    clientEvent.xclient.window = INVALID_WINDOWS + 1; // This is the first application window id
     QVERIFY(m_subject->testX11EventFilter(&clientEvent));
 
     // Make sure the window list change signal was emitted
     QCOMPARE(r.count, 1);
-
-    // There should be 3 windows in the window list
-    QCOMPARE(r.windowList.count(), 3);
-    QCOMPARE(r.windowList.at(0).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0));
-    QCOMPARE(r.windowList.at(1).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-    QCOMPARE(r.windowList.at(2).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 9));
+    // We have closed one window
+    QCOMPARE(r.windowList.count(), APPLICATION_WINDOWS - 1);
 
     // Change the client list so that the window being closed was actually closed
-    clientListNumberOfWindows = WINDOW_ATTRIBUTE_TEST_WINDOWS + 4;
     XEvent propertyEvent;
     propertyEvent.type = PropertyNotify;
     propertyEvent.xproperty.window = DefaultRootWindow(QX11Info::display());
-    propertyEvent.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", False);
+    propertyEvent.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", False);
     QVERIFY(m_subject->testX11EventFilter(&propertyEvent));
 
-    // Make sure the window list change signal was emitted
-    QCOMPARE(r.count, 2);
+    // Make sure the window list change signal was not emitted
+    QCOMPARE(r.count, 1);
 
     // There should be 2 windows in the window list
-    QCOMPARE(r.windowList.count(), 2);
-    QCOMPARE(r.windowList.at(0).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0));
-    QCOMPARE(r.windowList.at(1).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-
-    // Include all windows in the client list again and mark an inexisting window as a window being closed
-    clientListNumberOfWindows = NUMBER_OF_WINDOWS;
-    clientEvent.xclient.window = 0;
-    QVERIFY(m_subject->testX11EventFilter(&clientEvent));
-
-    // Make sure the window list change signal was emitted
-    QCOMPARE(r.count, 3);
-
-    // There should be 3 windows in the window list
-    QCOMPARE(r.windowList.count(), 4);
-    QCOMPARE(r.windowList.at(0).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 0));
-    QCOMPARE(r.windowList.at(1).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 4));
-    QCOMPARE(r.windowList.at(2).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 8));
-    QCOMPARE(r.windowList.at(3).window(), (Window)(WINDOW_ATTRIBUTE_TEST_WINDOWS + 9));
-}
-/*
-void Ut_HomeApplication::testContentSearchLaunch()
-{
-    // Add interface so that isValid() returns true
-    validInterfaces.append(QString("com.nokia.ContentSearchIf"));
-
-    // Launch the content search service
-    m_subject->launchContentSearchService();
-
-    // Verify that content search is launched
-    QCOMPARE(serviceInterfaces.count(), 1);
-    QCOMPARE(serviceInterfaces.at(0), QString("com.nokia.ContentSearchIf"));
-    QCOMPARE(asyncCallMethods.at(0), QString("launch"));
-    QCOMPARE(asyncCallArguments.at(0).count(), 1);
-    QCOMPARE(asyncCallArguments.at(0).at(0).type(), QVariant::String);
-    QCOMPARE(asyncCallArguments.at(0).at(0).toString(), QString(""));
-}
-
-void Ut_HomeApplication::testContentSearchLaunchWithoutServiceFW()
-{
-    // Click the search button
-    m_subject->launchContentSearchService();
-
-    // Verify that home application doesn't try to launch the service
-    QCOMPARE(serviceInterfaces.count(), 1);
-    QCOMPARE(serviceInterfaces.at(0), QString("com.nokia.ContentSearchIf"));
-    QCOMPARE(asyncCallMethods.count(), 0);
+    QCOMPARE(r.windowList.count(), APPLICATION_WINDOWS - 1);
 }
-*/
-void Ut_HomeApplication::testUpdateWindowList()
+
+void Ut_HomeApplication::testWindowStackingOrder()
 {
     WindowListReceiver r;
-    connect(m_subject, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), &r, SLOT(windowListUpdated(const QList<WindowInfo> &)));
+    connect(m_subject, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), &r, SLOT(stackingWindowListUpdated(const QList<WindowInfo> &)));
 
-    // Verify that a window list change was emitted when the application was visible.
     XEvent event;
-    event.type = PropertyNotify;
-    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST", False);
+    event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", False);
     event.xproperty.window = DefaultRootWindow(QX11Info::display());
+    event.type = PropertyNotify;
     QVERIFY(m_subject->testX11EventFilter(&event));
 
-    // Make sure the window list change signal was emitted
-    QCOMPARE(r.count, 1);
+    QCOMPARE(r.stackingCount, 1);
+    QCOMPARE(r.stackingWindowList.count(), VALID_WINDOWS);
+
+    WindowInfo first = r.stackingWindowList.first();
+    WindowInfo last = r.stackingWindowList.last();
+
+    QCOMPARE(first.window(), (unsigned long)(INVALID_WINDOWS));
+    QCOMPARE(last.window(), (unsigned long)g_windows.count() - 1);
+
+    Window tmp = g_windows[INVALID_WINDOWS];
+    g_windows[INVALID_WINDOWS] = g_windows.last();
+    g_windows[g_windows.count() - 1] = tmp;
+
+    QVERIFY(m_subject->testX11EventFilter(&event));
+    QCOMPARE(r.stackingCount, 2);
+    QCOMPARE(r.stackingWindowList.count(), VALID_WINDOWS);
+
+    QCOMPARE(first.window(), r.stackingWindowList.last().window());
+    QCOMPARE(last.window(), r.stackingWindowList.first().window());
 }
 
 void Ut_HomeApplication::testX11EventWindowNameChange_data()
 {
     QTest::addColumn<Window>("window");
     QTest::addColumn<QString>("property");
-    QTest::addColumn<QString>("title");
 
-    QTest::newRow("_NET_WM_NAME")
-            << (Window)WINDOW_ATTRIBUTE_TEST_WINDOWS + 0 << "_NET_WM_NAME" << "Window 0 _NET_WM_NAME changed title";
-    QTest::newRow("WM_NAME")
-            << (Window)WINDOW_ATTRIBUTE_TEST_WINDOWS + 4 << "WM_NAME" << "Test";
+    QTest::newRow("_NET_WM_NAME") << (Window) INVALID_WINDOWS + 1 << "_NET_WM_NAME";
 }
 
 void Ut_HomeApplication::testX11EventWindowNameChange()
 {
+    //    gWindowInfoStub->stubSetReturnValue("updateWindowTitle", true);
+    g_windowName = true;
     QFETCH(Window, window);
     QFETCH(QString, property);
-    QFETCH(QString, title);
 
-    WindowListReceiver r;
-    connect(m_subject, SIGNAL(windowTitleChanged(Window, QString)), &r, SLOT(changeWindowTitle(Window, QString)));
+    QSignalSpy spy(m_subject, SIGNAL(windowTitleChanged(Window, QString)));
 
     XEvent event;
     event.xproperty.atom = X11Wrapper::XInternAtom(QX11Info::display(), property.toUtf8(), False);
@@ -849,8 +674,14 @@
     event.xproperty.window = window;
     QVERIFY(m_subject->testX11EventFilter(&event));
 
-    QCOMPARE(r.changedTitle.first, window);
-    QCOMPARE(r.changedTitle.second, title);
+    QCOMPARE(spy.count(), 1);
+    g_windowName = false;
+    //    gWindowInfoStub->stubSetReturnValue("updateWindowTitle", false);
+
+    // Check that the signal is not emitted when the window info can not get the title
+    spy.clear();
+    QVERIFY(m_subject->testX11EventFilter(&event));
+    QCOMPARE(spy.count(), 0);
 }
 
 QTEST_APPLESS_MAIN(Ut_HomeApplication)
--- tests/ut_homeapplication/ut_homeapplication.h
+++ tests/ut_homeapplication/ut_homeapplication.h
@@ -31,21 +31,24 @@
     Q_OBJECT
 
 public:
-    WindowListReceiver() : count(0), stackCount(0) { }
+    WindowListReceiver() : count(0), stackingCount(0) { }
     QList<WindowInfo> windowList;
+    QList<WindowInfo> stackingWindowList;
     int count;
-    int stackCount;
+    int stackingCount;
 
     QPair<Window, QString> changedTitle;
 
 private slots:
+
     void windowListUpdated(const QList<WindowInfo> &windowList) {
         this->windowList = windowList;
         this->count++;
     }
 
-    void windowStackingChanged(const QList<WindowInfo> &windowList) {
-        this->stackCount++;
+    void stackingWindowListUpdated(const QList<WindowInfo> &windowList) {
+        this->stackingWindowList = windowList;
+        this->stackingCount++;
     }
 
     void changeWindowTitle(Window w, const QString &title)
@@ -102,15 +105,12 @@
     // Test X11EventFilter with PropertyNotify events
     void testX11EventFilterWithPropertyNotify();
     // Test X11EventFilter with VisibilityNotify events
-    void testX11EventFilterWithVisibilityNotify();
+//    void testX11EventFilterWithVisibilityNotify();
     // Test X11EventFilter with ClientMessage events
     void testX11EventFilterWithClientMessage();
-    // Test content search service launch
-    //void testContentSearchLaunch();
-    // Test content search service launch without service framework
-    //void testContentSearchLaunchWithoutServiceFW();
-    // Test updating windows list
-    void testUpdateWindowList();
+    // Test the stacking order signal
+    void testWindowStackingOrder();
+
     // Test data for test testX11EventWindowNameChange
     void testX11EventWindowNameChange_data();
     // Test that title change signal is emitted when X window property changes
--- tests/ut_homeapplication/ut_homeapplication.pro
+++ tests/ut_homeapplication/ut_homeapplication.pro
@@ -9,10 +9,10 @@
 
 # helper classes
 SOURCES += \
-    windowinfo.cpp \
     $$STUBSDIR/stubbase.cpp \
     $$SRCDIR/homescreenservice.cpp \
-    $$SRCDIR/homescreenadaptor.cpp
+    $$SRCDIR/homescreenadaptor.cpp \
+    $$SRCDIR/windowinfo.cpp
 
 # unit test and unit
 HEADERS += \
--- tests/ut_launcher/ut_launcher.cpp
+++ tests/ut_launcher/ut_launcher.cpp
@@ -29,11 +29,16 @@
 #include "launcherpagemodel.h"
 #include "mockdatastore.h"
 
+
+
 // LauncherButton stubs
 LauncherButton::LauncherButton(MWidget *parent) : MButton(parent, new LauncherButtonModel) {}
 LauncherButton::LauncherButton(const QString&, MWidget*parent) : MButton(parent, new LauncherButtonModel) {}
 LauncherButton::~LauncherButton(){}
 
+const static int BUTTONS_PER_PAGE = 12;
+
+
 QString LauncherButton::desktopEntry() const
 {
     return objectName();
@@ -49,16 +54,33 @@
 {
 }
 
-void QDBusPendingReplyData::setMetaTypes(int, int const *)
+void LauncherButton::retranslateUi()
+{
+}
+
+bool LauncherButton::isInProgress() const
+{
+    return false;
+}
+
+void LauncherButton::setProgressIndicatorTimeout(int)
 {
 }
 
-bool mApplicationIfProxyLaunchCalled;
-QDBusPendingReply<> MApplicationIfProxy::launch()
+void LauncherButton::hideProgressIndicator()
 {
-    mApplicationIfProxyLaunchCalled = true;
+}
 
-    return QDBusPendingReply<>();
+void LauncherButton::hideProgressIndicatorIfObscured(const QList<WindowInfo> &)
+{
+}
+
+void LauncherButton::init()
+{
+}
+
+void QDBusPendingReplyData::setMetaTypes(int, int const *)
+{
 }
 
 QString qProcessProgramStarted;
@@ -74,6 +96,13 @@
     return true;
 }
 
+void Ut_Launcher::addButtonsToLauncher(int amount)
+{
+    for (int i = 0; i < amount; i++) {
+        launcher->addLauncherButton(QString("testApp%1.desktop").arg(i));
+    }
+}
+
 // Tests
 void Ut_Launcher::initTestCase()
 {
@@ -91,12 +120,9 @@
     // Create a launcher and connect the signals
     launcher = new Launcher(launcherDataStore);
     connect(this, SIGNAL(directoryChanged(const QString)), launcher, SLOT(updatePagesFromDataStore()));
-    connect(this, SIGNAL(applicationLaunched(const QString)), launcher, SLOT(launchApplication(const QString)));
-    connect(this, SIGNAL(mApplicationLaunched(const QString)), launcher, SLOT(launchMApplication(const QString)));
     connect(this, SIGNAL(testPanToPageSignal(const QString &)), launcher, SLOT(panToPage(const QString &)));
 
     qProcessProgramStarted.clear();
-    mApplicationIfProxyLaunchCalled = false;
 
     updateFromDesktopEntryCallCount = 0;
 }
@@ -138,20 +164,6 @@
     QCOMPARE(arguments.at(0).toInt(), page);
 }
 
-void Ut_Launcher::testApplicationLaunched()
-{
-    launcher->startApplication("test0");
-
-    QCOMPARE(qProcessProgramStarted, QString("test0"));
-}
-
-void Ut_Launcher::testMApplicationLaunched()
-{
-    launcher->startMApplication("com.nokia.test1");
-
-    QCOMPARE(mApplicationIfProxyLaunchCalled, true);
-}
-
 void Ut_Launcher::testPaging()
 {
     launcher->setEnabled(true);
@@ -300,4 +312,82 @@
     QCOMPARE(updateFromDesktopEntryCallCount, 1);
 }
 
+void Ut_Launcher::testAddingButtons()
+{
+    launcher->setEnabled(true);
+
+    addButtonsToLauncher(BUTTONS_PER_PAGE);
+
+    QCOMPARE(launcher->model()->launcherPages().count(), 1);
+    QCOMPARE(launcher->model()->launcherPages().at(0)->model()->launcherButtons().count(), BUTTONS_PER_PAGE);
+}
+
+void Ut_Launcher::testAddingButtonsOnMultiplePages()
+{
+    launcher->setEnabled(true);
+
+    int buttonCountOnSecondPage = 3;
+    int addedButtons = BUTTONS_PER_PAGE + buttonCountOnSecondPage;
+    addButtonsToLauncher(addedButtons);
+
+    QCOMPARE(launcher->model()->launcherPages().count(), 2);
+    QCOMPARE(launcher->model()->launcherPages().at(0)->model()->launcherButtons().count(), BUTTONS_PER_PAGE);
+    QCOMPARE(launcher->model()->launcherPages().at(1)->model()->launcherButtons().count(), buttonCountOnSecondPage);
+}
+
+void Ut_Launcher::testAddingButtonsWithExistingButtons()
+{
+    launcher->setEnabled(true);
+
+    // Add some existing buttons
+    int initialButtons = BUTTONS_PER_PAGE/2;
+    QHash<QString, QVariant> dataForAllDesktopEntries;
+    for (int i = 0; i < initialButtons; i++) {
+        dataForAllDesktopEntries.insert(QString("noPlacement%1").arg(i), QVariant());
+    }
+
+    gLauncherDataStoreStub->stubSetReturnValue("dataForAllDesktopEntries", dataForAllDesktopEntries);
+    emit directoryChanged(APPLICATIONS_DIRECTORY);
+
+    // adding more buttons
+    int addedButtons = BUTTONS_PER_PAGE;
+    int buttonCountOnSecondPage = initialButtons;
+    addButtonsToLauncher(addedButtons);
+
+    QCOMPARE(launcher->model()->launcherPages().count(), 2);
+    QCOMPARE(launcher->model()->launcherPages().at(0)->model()->launcherButtons().count(), BUTTONS_PER_PAGE);
+    QCOMPARE(launcher->model()->launcherPages().at(1)->model()->launcherButtons().count(), buttonCountOnSecondPage);
+}
+
+void Ut_Launcher::testRemovingButtons()
+{
+    launcher->setEnabled(true);
+
+    // adding more than one page
+    int buttonCountOnFirstPage = BUTTONS_PER_PAGE;
+    int buttonCountOnSecondPage = 2;
+    int buttonCount = BUTTONS_PER_PAGE + buttonCountOnSecondPage;
+    addButtonsToLauncher(buttonCount);
+
+    // Make specific buttons to "simulate" removed buttons
+    launcher->model()->launcherPages().at(0).data()->model()->launcherButtons().at(3)->setObjectName("testApp2.desktop");
+    launcher->model()->launcherPages().at(0).data()->model()->launcherButtons().at(4)->setObjectName("testApp3.desktop");
+
+    // remove 2 buttons from 1st page
+    buttonCountOnFirstPage = BUTTONS_PER_PAGE - 2;
+    launcher->removeLauncherButton("testApp2.desktop");
+    launcher->removeLauncherButton("testApp3.desktop");
+
+    QCOMPARE(launcher->model()->launcherPages().count(), 2);
+    QCOMPARE(launcher->model()->launcherPages().at(0)->model()->launcherButtons().count(), buttonCountOnFirstPage);
+    QCOMPARE(launcher->model()->launcherPages().at(1)->model()->launcherButtons().count(), buttonCountOnSecondPage);
+}
+
+void Ut_Launcher::testSettingLauncherToFirstPage()
+{
+    QSignalSpy spy(launcher, SIGNAL(focusToFirstPageRequested()));
+    launcher->setFirstPage();
+    QCOMPARE(spy.count(), 1);
+}
+
 QTEST_MAIN(Ut_Launcher)
--- tests/ut_launcher/ut_launcher.h
+++ tests/ut_launcher/ut_launcher.h
@@ -43,6 +43,8 @@
     void createdDefaultSetOfDesktopEntries();
     // Convience function for pantToPage tests to check that signal has correct page as an argument
     void comparePageNumberArgument(QSignalSpy &spy, int page);
+    // adds buttons to launcher
+    void addButtonsToLauncher(int amount);
 
 signals:
     void directoryLaunched(const QString &directory, const QString &title = QString(), const QString &iconId = QString());
@@ -61,10 +63,6 @@
     // Executed once after last test case
     void cleanupTestCase();
 
-    // Test that launching an Application is attempted
-    void testApplicationLaunched();
-    // Test that launching a MApplication is attempted
-    void testMApplicationLaunched();
     // Test that launcher buttons are paged to multiple pages
     void testPaging();
     // Test that empty page is removed from launcher
@@ -84,5 +82,15 @@
     void testPanToPageWithEmptyFileName();
     // Test that launcher button is updated when signal received
     void testUpdatingLauncherButton();
+    // Test adding buttons
+    void testAddingButtons();
+    // Test adding buttons on multiple pages
+    void testAddingButtonsOnMultiplePages();
+    // Test adding buttons test adding button when there are existing buttons
+    void testAddingButtonsWithExistingButtons();
+    // Test removing buttons
+    void testRemovingButtons();
+    // Test setting launcher to show first page
+    void testSettingLauncherToFirstPage();
 };
 #endif //_UT_LAUNCHER_
--- tests/ut_launcher/ut_launcher.pro
+++ tests/ut_launcher/ut_launcher.pro
@@ -8,16 +8,18 @@
 SOURCES += \
     ut_launcher.cpp \
     $$SRCDIR/launcher.cpp \
+    $$SRCDIR/launcheraction.cpp \
     $$SRCDIR/launcherpage.cpp
 
 # service classes
 SOURCES += \
-    $$STUBSDIR\stubbase.cpp
+    $$STUBSDIR/stubbase.cpp
 
 # unit test and unit classes
 HEADERS += \
     ut_launcher.h \
     $$SRCDIR/launcher.h \
+    $$SRCDIR/launcheraction.h \
     $$SRCDIR/launcherpage.h \
     $$SRCDIR/launchermodel.h \
     $$SRCDIR/launcherdatastore.h \
--- tests/ut_launcherbutton/ut_launcherbutton.cpp
+++ tests/ut_launcherbutton/ut_launcherbutton.cpp
@@ -18,16 +18,314 @@
 ****************************************************************************/
 
 #include <QtTest/QtTest>
-#include <MApplication>
+#include "contentaction.h"
 #include "ut_launcherbutton.h"
 #include "launcherbutton.h"
 #include "launcher_stub.h"
+#include "homeapplication_stub.h"
+#include "x11wrapper.h"
+
+#define ATOM_TYPE_NORMAL 1
+#define ATOM_TYPE_NOTIFICATION 2
+#define ATOM_TYPE_MENU 3
+#define ATOM_TYPE_DIALOG 4
+#define ATOM_TYPE_DESKTOP 5
+#define ATOM_TYPE_DEFAULT 6
+
+// X11Wrapper Stubs
+int X11Wrapper::XSelectInput(Display *, Window , long)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWindowAttributes(Display *, Window, XWindowAttributes *)
+{
+    return 0;
+}
+
+Atom X11Wrapper::XInternAtom(Display *, const char *atom_name, Bool)
+{
+    if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
+        return ATOM_TYPE_NORMAL;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_NOTIFICATION") == 0) {
+        return ATOM_TYPE_NOTIFICATION;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_MENU") == 0) {
+        return ATOM_TYPE_MENU;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
+        return ATOM_TYPE_DIALOG;
+    } else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DESKTOP") == 0) {
+        return ATOM_TYPE_DESKTOP;
+    } else {
+        return ATOM_TYPE_DEFAULT;
+    }
+}
+
+int X11Wrapper::XGetWindowProperty(Display *dpy, Window w, Atom property, long long_offset, long long_length, Bool del, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return)
+{
+    Q_UNUSED(dpy);
+    Q_UNUSED(property);
+    Q_UNUSED(long_offset);
+    Q_UNUSED(long_length);
+    Q_UNUSED(del);
+    Q_UNUSED(req_type);
+    Q_UNUSED(actual_type_return);
+    Q_UNUSED(actual_format_return);
+    Q_UNUSED(bytes_after_return);
+
+    if (w == ATOM_TYPE_NORMAL) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_NORMAL;
+        return Success;
+    } else if (w == ATOM_TYPE_NOTIFICATION) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_NOTIFICATION;
+        return Success;
+    } else if (w == ATOM_TYPE_MENU) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_MENU;
+        return Success;
+    } else if (w == ATOM_TYPE_DIALOG) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_DIALOG;
+        return Success;
+    } else if (w == ATOM_TYPE_DESKTOP) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_DESKTOP;
+        return Success;
+    } else if (w == ATOM_TYPE_DEFAULT) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_DEFAULT;
+        return Success;
+    } else {
+        return BadAtom;
+    }
+}
+
+int X11Wrapper::XFree(void *)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWMName(Display *, Window, XTextProperty *)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetTextProperty(Display *, Window , XTextProperty *, Atom)
+{
+    return 0;
+}
+
+XWMHints *X11Wrapper::XGetWMHints(Display *, Window)
+{
+    return 0;
+}
+
+int X11Wrapper::XFreePixmap(Display *, Pixmap)
+{
+    return 0;
+}
+
+Pixmap X11Wrapper::XCompositeNameWindowPixmap(Display *, Window)
+{
+    return 0;
+}
+
+Damage X11Wrapper::XDamageCreate(Display *, Drawable, int)
+{
+    return 0;
+}
+
+void X11Wrapper::XDamageDestroy(Display *, Damage)
+{
+
+}
+
+int X11Wrapper::XSync(Display *, Bool)
+{
+    return 0;
+}
+
+XErrorHandler X11Wrapper::XSetErrorHandler(XErrorHandler)
+{
+    return 0;
+}
+
+int X11Wrapper::XChangeProperty(Display *, Window, Atom, Atom, int, int, unsigned char *, int)
+{
+    return 0;
+}
+
+Status X11Wrapper::XSendEvent(Display *, Window, Bool, long, XEvent *)
+{
+    return 0;
+}
+
+using namespace ContentAction;
+
+QString language;
+QMap< QString, QSharedPointer<ActionPrivate> > contentActionPrivate;
+
+// LauncherAction stubs (used by LauncherButton)
+LauncherAction::LauncherAction()
+    : Action()
+{
+}
+
+LauncherAction::LauncherAction(const QString& desktopEntry)
+    : Action(Action::defaultActionForFile(desktopEntry, ""))
+{
+}
+
+bool operator!=(const LauncherAction &a, const LauncherAction &b)
+{
+    Q_UNUSED(a);
+    Q_UNUSED(b);
+    return true;
+}
+
+// ContentAction stubs (used by LauncherAction)
+struct ContentAction::ActionPrivate
+{
+    ActionPrivate(bool isValid, QString name,
+                  QString english, QString nonEnglish,
+                  QString icon) :
+        isValid_(isValid), name_(name),
+        english_(english), nonEnglish_(nonEnglish),
+        icon_(icon) {};
+    virtual ~ActionPrivate() {};
+
+    virtual bool isValid() const { return isValid_; }
+    virtual QString name() const { return  name_; }
+    virtual QString localizedName() const {
+       if (language == "english") {
+           return english_;
+       } else {
+           return nonEnglish_;
+       }
+    }
+    virtual QString icon() const { return icon_; }
+
+    bool isValid_;
+    QString name_;
+    QString english_;
+    QString nonEnglish_;
+    QString icon_;
+};
+
+bool Action::isValid() const { return d->isValid(); }
+QString Action::name() const { return d->name(); } 
+QString Action::localizedName() const { return d->localizedName(); } 
+QString Action::icon() const { return d->icon(); } 
+
+Action::Action()
+    : d(new ActionPrivate(false, "", "", "", ""))
+{
+}
+
+Action::Action(const Action& other)
+    : d(other.d)
+{
+}
+
+Action::~Action()
+{
+}
+
+Action Action::defaultActionForFile(const QUrl& fileUri, const QString& mimeType)
+{
+    Q_UNUSED(mimeType);
+
+    QString fileName = fileUri.toString();
+    QSharedPointer<ActionPrivate> priv =
+       contentActionPrivate.value(fileName);
+
+    Action action;
+    action.d = priv;
+
+    return action;
+}
+
+int contentActionTriggerCalls = 0;
+void Action::trigger() const
+{
+    contentActionTriggerCalls++;
+}
+
+// A helper function to set up a contentActionPrivate entry
+void addActionPrivate(QString fileName, bool isValid, QString name,
+                      QString english, QString nonEnglish, QString icon)
+{
+    ActionPrivate* priv = new ActionPrivate(isValid, 
+                                            name,
+                                            english,
+                                            nonEnglish,
+                                            icon);
+    contentActionPrivate.insert(fileName,
+                                QSharedPointer<ActionPrivate>(priv));
+}
+
+// QIcon stubs
+QString qIconFileName;
+QIcon::QIcon(const QString &fileName)
+{
+    qIconFileName = fileName;
+}
+
+QIcon& QIcon::operator=(QIcon const &)
+{
+    return *this;
+}
+
+QIcon::~QIcon()
+{
+}
+
+bool qIconHasThemeIcon = false;
+bool QIcon::hasThemeIcon(const QString &name)
+{
+    Q_UNUSED(name);
+    return qIconHasThemeIcon;
+}
+
+QString qIconName;
+QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
+{
+    qIconName = name;
+    return fallback;
+}
+
+// QTimer stubs
+bool qTimerStarted;
+void QTimer::start()
+{
+    qTimerStarted = true;
+    id = 0;
+}
+
+void QTimer::stop()
+{
+    qTimerStarted = false;
+    id = -1;
+}
 
 void Ut_LauncherButton::initTestCase()
 {
     static int argc = 1;
     static char *app_name[1] = { (char *) "./ut_launcherbutton" };
-    app = new MApplication(argc, app_name);
+    app = new HomeApplication(argc, app_name);
 }
 
 void Ut_LauncherButton::cleanupTestCase()
@@ -37,31 +335,148 @@
 
 void Ut_LauncherButton::init()
 {
+    language = "english";
+    qIconFileName.clear();
+    qIconName.clear();
+    qIconHasThemeIcon = false;
+    contentActionPrivate.clear();
+    contentActionTriggerCalls = 0;
+    qTimerStarted = false;
+
     m_subject = new LauncherButton();
     connect(this, SIGNAL(clicked()), m_subject, SLOT(launch()));
+    connect(this, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), m_subject, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &)));
 }
 
 void Ut_LauncherButton::cleanup()
 {
+    m_subject->hideProgressIndicator();
+    delete m_subject;
+}
+
+void Ut_LauncherButton::testInitialization()
+{
+    delete m_subject;
+
+    addActionPrivate("/dev/null",
+                     true,
+                     "name",
+                     "english",
+                     "nonenglish",
+                     "icon");
+
+    m_subject = new LauncherButton("/dev/null");
+    QCOMPARE(m_subject->desktopEntry(), QString("/dev/null"));
+    QCOMPARE(m_subject->text(), QString("english"));
+    QCOMPARE(m_subject->iconID(), QString("icon"));
+    QVERIFY(disconnect(&m_subject->progressIndicatorTimeoutTimer, SIGNAL(timeout()), m_subject, SLOT(hideProgressIndicator())));
+    QVERIFY(m_subject->progressIndicatorTimeoutTimer.isSingleShot());
+    QVERIFY(!qTimerStarted);
+}
+
+void Ut_LauncherButton::testInitializationAbsoluteIcon()
+{
     delete m_subject;
+
+    addActionPrivate("/dev/null",
+                     true,
+                     "name",
+                     "english",
+                     "nonenglish",
+                     "/icon");
+
+    m_subject = new LauncherButton("/dev/null");
+    QCOMPARE(m_subject->iconID(), QString());
+    QCOMPARE(qIconFileName, QString("/icon"));
 }
 
-void Ut_LauncherButton::testLaunchApplication()
+void Ut_LauncherButton::testInitializationFreeDesktopIcon()
 {
-    m_subject->setTargetType("Application");
-    m_subject->setTarget("testApplication");
+    delete m_subject;
+
+    addActionPrivate("/dev/null",
+                     true,
+                     "name",
+                     "english",
+                     "nonenglish",
+                     "icon");
+    qIconHasThemeIcon = true;
+
+    m_subject = new LauncherButton("/dev/null");
+    QCOMPARE(m_subject->iconID(), QString());
+    QCOMPARE(qIconName, QString("icon"));
+}
+
+void Ut_LauncherButton::testLaunch()
+{
+    emit clicked();
+    QCOMPARE(contentActionTriggerCalls, 1);
+    QVERIFY(qTimerStarted);
+    QVERIFY(disconnect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), m_subject, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &))));
+    QVERIFY(m_subject->isInProgress());
+
+    qTimerStarted = false;
     emit clicked();
-    QCOMPARE(gLauncherStub->stubCallCount("startApplication"), 1);
-    QCOMPARE(gLauncherStub->stubLastCallTo("startApplication").parameter<QString>(0), m_subject->target());
+    QVERIFY(!qTimerStarted);
+    QVERIFY(!disconnect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), m_subject, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &))));
 }
 
-void Ut_LauncherButton::testLaunchMApplication()
+void Ut_LauncherButton::testHideProgressIndicator()
 {
-    m_subject->setTargetType("Service");
-    m_subject->setTarget("testService");
     emit clicked();
-    QCOMPARE(gLauncherStub->stubCallCount("startMApplication"), 1);
-    QCOMPARE(gLauncherStub->stubLastCallTo("startMApplication").parameter<QString>(0), m_subject->target());
+    m_subject->hideProgressIndicator();
+    QVERIFY(!qTimerStarted);
+    QVERIFY(!disconnect(qApp, SIGNAL(windowStackingOrderChanged(const QList<WindowInfo> &)), m_subject, SLOT(hideProgressIndicatorIfObscured(const QList<WindowInfo> &))));
+    QVERIFY(!m_subject->isInProgress());
+}
+
+void Ut_LauncherButton::testHideProgressIndicatorIfObscured_data()
+{
+    QTest::addColumn<int>("topMostWindowId");
+    QTest::addColumn<bool>("shouldBeInProgress");
+
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_NORMAL") << 1 << false;
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_NOTIFICATION") << 2 << true;
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_MENU") << 3 << true;
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_DIALOG") << 4 << true;
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_DESKTOP") << 5 << true;
+    QTest::newRow("_NEW_WM_WINDOW_TYPE_DEFAULT") << 6 << false;
+}
+
+void Ut_LauncherButton::testHideProgressIndicatorIfObscured()
+{
+    QFETCH(int, topMostWindowId);
+    QFETCH(bool, shouldBeInProgress);
+
+    emit clicked();
+    QCOMPARE(m_subject->isInProgress(), true);
+
+    QList<WindowInfo> windowList;
+    windowList.append(WindowInfo(topMostWindowId));
+    emit windowStackingOrderChanged(windowList);
+
+    QCOMPARE(m_subject->isInProgress(), shouldBeInProgress);
+}
+
+void Ut_LauncherButton::testLanguageChange()
+{
+    delete m_subject;
+
+    addActionPrivate("/dev/null",
+                     true,
+                     "name",
+                     "english",
+                     "nonenglish",
+                     "icon");
+
+    m_subject = new LauncherButton("/dev/null");
+    QCOMPARE(m_subject->text(), QString("english"));
+
+    language = "otherlang";
+    m_subject->retranslateUi();
+    QCOMPARE(m_subject->text(), QString("nonenglish"));
 }
 
 QTEST_APPLESS_MAIN(Ut_LauncherButton)
+
+//     QCOMPARE(m_subject->progressIndicatorTimeoutTimer.interval(), m_subject->style()->progressIndicatorTimeout());
--- tests/ut_launcherbutton/ut_launcherbutton.h
+++ tests/ut_launcherbutton/ut_launcherbutton.h
@@ -21,8 +21,9 @@
 #define UT_LAUNCHERBUTTON_H
 
 #include <QObject>
+#include "windowinfo.h"
 
-class MApplication;
+class HomeApplication;
 class LauncherButton;
 
 class Ut_LauncherButton : public QObject
@@ -40,15 +41,22 @@
     void cleanup();
 
     // Test cases
-    void testLaunchApplication();
-    void testLaunchMApplication();
+    void testInitialization();
+    void testInitializationAbsoluteIcon();
+    void testInitializationFreeDesktopIcon();
+    void testLanguageChange();
+    void testLaunch();
+    void testHideProgressIndicator();
+    void testHideProgressIndicatorIfObscured();
+    void testHideProgressIndicatorIfObscured_data();
 
 signals:
     void clicked();
+    void windowStackingOrderChanged(const QList<WindowInfo> &windowList);
 
 private:
-    // MApplication
-    MApplication *app;
+    // Application
+    HomeApplication *app;
     // The object being tested
     LauncherButton *m_subject;
 };
--- tests/ut_launcherbutton/ut_launcherbutton.pro
+++ tests/ut_launcherbutton/ut_launcherbutton.pro
@@ -6,7 +6,8 @@
 # unit test and unit
 SOURCES += \
     ut_launcherbutton.cpp \
-    $$SRCDIR/launcherbutton.cpp
+    $$SRCDIR/launcherbutton.cpp \
+    $$SRCDIR/windowinfo.cpp
 
 # base classes
 SOURCES += \
@@ -17,6 +18,9 @@
     ut_launcherbutton.h \
     $$SRCDIR/launcherbutton.h \
     $$SRCDIR/launcherbuttonmodel.h \
-    $$SRCDIR/launcher.h
+    $$SRCDIR/launcher.h \
+    $$SRCDIR/windowinfo.h \
+    $$SRCDIR/x11wrapper.h \
+    $$SRCDIR/homeapplication.h
 
 include(../common_bot.pri)
--- tests/ut_launcherbuttonview
+++ tests/ut_launcherbuttonview
+(directory)
--- tests/ut_launcherbuttonview/ut_launcherbuttonview.cpp
+++ tests/ut_launcherbuttonview/ut_launcherbuttonview.cpp
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <MApplication>
+#include <MProgressIndicator>
+#include "ut_launcherbuttonview.h"
+#include "launcherbuttonview.h"
+#include "launcherbutton_stub.h"
+#include "launcheraction_stub.h"
+#include "windowinfo_stub.h"
+
+// QTimer stubs
+bool qTimerStarted;
+void QTimer::start()
+{
+    qTimerStarted = true;
+    id = 0;
+}
+
+void QTimer::stop()
+{
+    qTimerStarted = false;
+    id = -1;
+}
+
+// QTimeLine stubs
+bool qTimeLineStarted;
+void QTimeLine::start()
+{
+    qTimeLineStarted = true;
+}
+
+void QTimeLine::stop()
+{
+    qTimeLineStarted = false;
+}
+
+QTimeLine::State QTimeLine::state() const
+{
+    return qTimeLineStarted ? QTimeLine::Running : QTimeLine::NotRunning;
+}
+
+// MButton stubs
+QString mButtonText;
+QString MButton::text() const
+{
+    return mButtonText;
+}
+
+// MButtonIconView stubs
+bool mButtonIconViewApplyStyleCalled;
+void MButtonIconView::applyStyle()
+{
+    mButtonIconViewApplyStyleCalled = true;
+}
+
+bool mWidgetViewUpdateCalled;
+void MWidgetView::update(const QRectF &)
+{
+    mWidgetViewUpdateCalled = true;
+}
+
+void Ut_LauncherButtonView::initTestCase()
+{
+    static int argc = 1;
+    static char *app_name[1] = { (char *) "./ut_launcherbuttonview" };
+    app = new MApplication(argc, app_name);
+    mButtonText = "test";
+}
+
+void Ut_LauncherButtonView::cleanupTestCase()
+{
+    delete app;
+}
+
+void Ut_LauncherButtonView::init()
+{
+    qTimeLineStarted = false;
+    qTimerStarted = false;
+    controller = new LauncherButton;
+    controller->setModel(new LauncherButtonModel);
+    m_subject = new LauncherButtonView(controller);
+    controller->setView(m_subject);
+    connect(this, SIGNAL(frameChanged(int)), m_subject, SLOT(setProgressIndicatorFrame(int)));
+    mWidgetViewUpdateCalled = false;
+    mButtonIconViewApplyStyleCalled = false;
+}
+
+void Ut_LauncherButtonView::cleanup()
+{
+    delete controller;
+}
+
+void Ut_LauncherButtonView::testInitialization()
+{
+    QVERIFY(disconnect(&m_subject->progressIndicatorTimer, SIGNAL(timeout()), m_subject, SLOT(showProgressIndicator())));
+    QVERIFY(disconnect(&m_subject->progressIndicatorTimeLine, SIGNAL(frameChanged(int)), m_subject, SLOT(setProgressIndicatorFrame(int))));
+
+    QVERIFY(m_subject->progressIndicatorTimer.isSingleShot());
+    QCOMPARE(m_subject->progressIndicatorTimeLine.state(), QTimeLine::NotRunning);
+    QCOMPARE(m_subject->progressIndicatorTimeLine.loopCount(), 0);
+    QCOMPARE(m_subject->progressIndicatorTimeLine.curveShape(), QTimeLine::LinearCurve);
+}
+
+void Ut_LauncherButtonView::testApplyStyle()
+{
+    LauncherButtonStyle *style = const_cast<LauncherButtonStyle *>(m_subject->style().operator ->());
+    style->setProgressIndicatorTimeout(12345);
+
+    m_subject->applyStyle();
+    QVERIFY(mButtonIconViewApplyStyleCalled);
+    QCOMPARE(gLauncherButtonStub->stubLastCallTo("setProgressIndicatorTimeout").parameter<int>(0), m_subject->style()->progressIndicatorTimeout());
+}
+
+void Ut_LauncherButtonView::testUpdateData()
+{
+    controller->model()->setShowProgressIndicator(true);
+    QCOMPARE(m_subject->progressIndicatorTimer.isActive(), true);
+
+    controller->model()->setShowProgressIndicator(false);
+    QCOMPARE(m_subject->progressIndicatorTimer.isActive(), false);
+}
+
+void Ut_LauncherButtonView::testShowProgressIndicator()
+{
+    m_subject->showProgressIndicator();
+    QCOMPARE(m_subject->progressIndicatorTimeLine.state(), QTimeLine::Running);
+    QVERIFY(mWidgetViewUpdateCalled);
+
+    mWidgetViewUpdateCalled = false;
+    m_subject->showProgressIndicator();
+    QVERIFY(!mWidgetViewUpdateCalled);
+}
+
+void Ut_LauncherButtonView::testHideProgressIndicator()
+{
+    m_subject->showProgressIndicator();
+
+    mWidgetViewUpdateCalled = false;
+    m_subject->hideProgressIndicator();
+    QCOMPARE(m_subject->progressIndicatorTimer.isActive(), false);
+    QCOMPARE(m_subject->progressIndicatorTimeLine.state(), QTimeLine::NotRunning);
+    QVERIFY(mWidgetViewUpdateCalled);
+}
+
+void Ut_LauncherButtonView::testSetProgressIndicatorFrame()
+{
+    emit frameChanged(5);
+    QVERIFY(mWidgetViewUpdateCalled);
+}
+
+QTEST_APPLESS_MAIN(Ut_LauncherButtonView)
--- tests/ut_launcherbuttonview/ut_launcherbuttonview.h
+++ tests/ut_launcherbuttonview/ut_launcherbuttonview.h
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (directui at nokia.com)
+**
+** This file is part of mhome.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at directui at nokia.com.
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef UT_LAUNCHERBUTTONVIEW_H
+#define UT_LAUNCHERBUTTONVIEW_H
+
+#include <QObject>
+
+class MApplication;
+class LauncherButton;
+class LauncherButtonView;
+
+class Ut_LauncherButtonView : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    // Called before the first testfunction is executed
+    void initTestCase();
+    // Called after the last testfunction was executed
+    void cleanupTestCase();
+    // Called before each testfunction is executed
+    void init();
+    // Called after every testfunction
+    void cleanup();
+
+    // Test cases
+    void testInitialization();
+    void testApplyStyle();
+    void testUpdateData();
+    void testShowProgressIndicator();
+    void testHideProgressIndicator();
+    void testSetProgressIndicatorFrame();
+
+signals:
+    void frameChanged(int frame);
+
+private:
+    // MApplication
+    MApplication *app;
+    // The object being tested
+    LauncherButtonView *m_subject;
+    // Controller for the object
+    LauncherButton *controller;
+};
+
+#endif
--- tests/ut_launcherbuttonview/ut_launcherbuttonview.pro
+++ tests/ut_launcherbuttonview/ut_launcherbuttonview.pro
+include(../common_top.pri)
+TARGET = ut_launcherbuttonview
+
+STYLE_HEADERS += $$SRCDIR/launcherbuttonstyle.h
+MODEL_HEADERS += $$SRCDIR/launcherbuttonmodel.h
+
+# unit test and unit
+SOURCES += \
+    ut_launcherbuttonview.cpp \
+    $$SRCDIR/launcherbuttonview.cpp \
+    $$STUBSDIR/stubbase.cpp
+
+HEADERS += \
+    ut_launcherbuttonview.h \
+    $$SRCDIR/launcherbuttonview.h \
+    $$SRCDIR/launcherbuttonmodel.h \
+    $$SRCDIR/launcherbuttonstyle.h \
+    $$SRCDIR/launcheraction.h \
+    $$SRCDIR/launcherbutton.h \
+    $$SRCDIR/windowinfo.h
+
+include(../common_bot.pri)
--- tests/ut_launcherdatastore/ut_launcherdatastore.cpp
+++ tests/ut_launcherdatastore/ut_launcherdatastore.cpp
@@ -120,6 +120,11 @@
     return addedWatcherPathCalls;
 }
 
+bool QFile::exists(const QString &)
+{
+    return true;
+}
+
 // QTimer stubs
 bool qTimerStarted;
 void QTimer::start()
@@ -247,17 +252,20 @@
     addDesktopEntry("testApplication3.desktop", "Test3", "Application", "Icon-camera", "test3");
     addDesktopEntry("testApplication4.desktop", "Test4", "Application", "Icon-camera", "test4");
     LauncherDataStore dataStore(mockStore);
-    QSignalSpy spy(&dataStore, SIGNAL(dataStoreChanged()));
+    QSignalSpy spyDesktopEntryAdded(&dataStore, SIGNAL(desktopEntryAdded(QString)));
+    QSignalSpy spyDataStoreChanged(&dataStore, SIGNAL(dataStoreChanged()));
     connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
     emit timeout();
 
     // The amount of files processed (N) is currently 3
     QHash<QString, QVariant> data = dataStore.dataForAllDesktopEntries();
     QCOMPARE(data.count(), 3);
+    // Verify that we have had an added signal for every processed file
+    QCOMPARE(spyDesktopEntryAdded.count(), 3);
 
     // Since there are items remaining the timer should be started and dataStoreChanged() should not be emitted
     QVERIFY(qTimerStarted);
-    QCOMPARE(spy.count(), 0);
+    QCOMPARE(spyDataStoreChanged.count(), 0);
 }
 
 void Ut_LauncherDataStore::testProcessUpdateQueueFinishesProcessingCorrectly()
@@ -267,7 +275,8 @@
     addDesktopEntry("testApplication3.desktop", "Test3", "Application", "Icon-camera", "test3");
     addDesktopEntry("testApplication4.desktop", "Test4", "Application", "Icon-camera", "test4");
     LauncherDataStore dataStore(mockStore);
-    QSignalSpy spy(&dataStore, SIGNAL(dataStoreChanged()));
+    QSignalSpy spyDesktopEntryAdded(&dataStore, SIGNAL(desktopEntryAdded(QString)));
+    QSignalSpy spyDataStoreChanged(&dataStore, SIGNAL(dataStoreChanged()));
     connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
     emit timeout();
 
@@ -277,10 +286,15 @@
 
     QHash<QString, QVariant> data = dataStore.dataForAllDesktopEntries();
     QCOMPARE(data.count(), 4);
+    QCOMPARE(spyDesktopEntryAdded.count(), 4);
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication1.desktop")));
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication2.desktop")));
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication3.desktop")));
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication4.desktop")));
 
     // Since there are no items remaining the timer should not be started and dataStoreChanged() should be emitted
     QVERIFY(!qTimerStarted);
-    QCOMPARE(spy.count(), 1);
+    QCOMPARE(spyDataStoreChanged.count(), 1);
 }
 
 void Ut_LauncherDataStore::testProcessUpdateQueueRestartsIfRequested()
@@ -305,6 +319,7 @@
     addDesktopEntry("testApplication3.desktop", "Test3", "Application", "Icon-camera", "test3");
     addDesktopEntry("testApplication4.desktop", "Test4", "Application", "Icon-camera", "test4");
     LauncherDataStore dataStore(mockStore);
+    QSignalSpy spyDesktopEntryRemoved(&dataStore, SIGNAL(desktopEntryRemoved(QString)));
     connect(this, SIGNAL(directoryChanged()), &dataStore, SLOT(updateDataFromDesktopEntryFiles()));
     connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
     emit timeout();
@@ -321,6 +336,11 @@
     data = dataStore.dataForAllDesktopEntries();
     QCOMPARE(data.count(), 1);
     QCOMPARE(data.contains(fileNameWithPath("testApplication.desktop")), true);
+    QCOMPARE(spyDesktopEntryRemoved.count(), 4);
+    QCOMPARE(spyDesktopEntryRemoved.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication1.desktop")));
+    QCOMPARE(spyDesktopEntryRemoved.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication2.desktop")));
+    QCOMPARE(spyDesktopEntryRemoved.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication3.desktop")));
+    QCOMPARE(spyDesktopEntryRemoved.takeFirst().at(0).toString(), QString(fileNameWithPath("testApplication4.desktop")));
 }
 
 void Ut_LauncherDataStore::testProcessUpdateQueueFiltersDesktopFiles()
@@ -336,10 +356,14 @@
     desktopEntryNotShowIn.insert(fileNameWithPath("notShowInMeeGoApplication.desktop"), QStringList() << "X-MeeGo");
 
     LauncherDataStore dataStore(mockStore);
+    QSignalSpy spyDesktopEntryAdded(&dataStore, SIGNAL(desktopEntryAdded(QString)));
     connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
     emit timeout();
     emit timeout();
 
+    QCOMPARE(spyDesktopEntryAdded.count(), 2);
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("onlyShowInMeeGoApplication.desktop")));
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("regularApplication.desktop")));
     // The data store should contain two entries and the default value should be empty
     QHash<QString, QVariant> data = dataStore.dataForAllDesktopEntries();
     QCOMPARE(data.count(), 2);
@@ -435,4 +459,53 @@
     QCOMPARE(addedWatcherPathCalls.at(3), fileNameWithPath("testApplication3.desktop"));
 }
 
+void Ut_LauncherDataStore::testUpdatingDesktopEntry()
+{
+    addDesktopEntry("testApplication1.desktop", "Test1", "Application", "Icon-camera", "test1");
+    addDesktopEntry("testApplication2.desktop", "Test2", "Application", "Icon-camera", "test2");
+    LauncherDataStore dataStore(mockStore);
+    connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
+    emit timeout();
+
+    QSignalSpy spyDesktopEntryChanged(&dataStore, SIGNAL(desktopEntryChanged(QString)));
+    QSignalSpy spyDataStoreChanged(&dataStore, SIGNAL(dataStoreChanged()));
+    connect(this, SIGNAL(fileChanged(QString)), &dataStore, SLOT(updateDesktopEntry(QString)));
+    emit fileChanged(fileNameWithPath("testApplication1.desktop"));
+    // No data store change when entry is just updated
+    QCOMPARE(spyDataStoreChanged.count(), 0);
+    QCOMPARE(spyDesktopEntryChanged.count(), 1);
+    QList<QVariant> arguments = spyDesktopEntryChanged.takeFirst();
+    QCOMPARE(arguments.at(0).toString(), QString(fileNameWithPath("testApplication1.desktop")));
+}
+
+void Ut_LauncherDataStore::testUpdatingInvalidEntry()
+{
+    addDesktopEntry("invalidAndValidApplication.desktop", "Test3", "invalid", "Icon-camera", "test3");
+    addDesktopEntry("testApplication2.desktop", "Test2", "Application", "Icon-camera", "test2");
+    LauncherDataStore dataStore(mockStore);
+    connect(this, SIGNAL(fileChanged(QString)), &dataStore, SLOT(updateDesktopEntry(QString)));
+    connect(this, SIGNAL(timeout()), &dataStore, SLOT(processUpdateQueue()));
+    emit timeout();
+
+    // connect signals only after entries have been added first time
+    QSignalSpy spyDataStoreChanged(&dataStore, SIGNAL(dataStoreChanged()));
+    QSignalSpy spyDesktopEntryAdded(&dataStore, SIGNAL(desktopEntryAdded(QString)));
+    QSignalSpy spyDesktopEntryRemoved(&dataStore, SIGNAL(desktopEntryRemoved(QString)));
+
+    // change to valid and send changed
+    desktopEntryType.insert(fileNameWithPath("invalidAndValidApplication.desktop"), QString("Application"));
+    emit fileChanged(fileNameWithPath("invalidAndValidApplication.desktop"));
+
+    QCOMPARE(spyDesktopEntryAdded.count(), 1);
+    QCOMPARE(spyDesktopEntryAdded.takeFirst().at(0).toString(), QString(fileNameWithPath("invalidAndValidApplication.desktop")));
+    QCOMPARE(spyDataStoreChanged.count(), 1);
+
+    // change back to invalid and send changed
+    desktopEntryType.insert(fileNameWithPath("invalidAndValidApplication.desktop"), QString("invalid_again"));
+    emit fileChanged(fileNameWithPath("invalidAndValidApplication.desktop"));
+
+    QCOMPARE(spyDesktopEntryRemoved.count(), 1);
+    QCOMPARE(spyDataStoreChanged.count(), 2);
+}
+
 QTEST_APPLESS_MAIN(Ut_LauncherDataStore)
--- tests/ut_launcherdatastore/ut_launcherdatastore.h
+++ tests/ut_launcherdatastore/ut_launcherdatastore.h
@@ -55,6 +55,8 @@
     void testUpdatingDataForDesktopEntry();
     void testOnlyPrefixedKeys();
     void testAddingWatcherDesktopEntryPaths();
+    void testUpdatingDesktopEntry();
+    void testUpdatingInvalidEntry();
 
 signals:
     void directoryChanged();
--- tests/ut_launcherpage/ut_launcherpage.cpp
+++ tests/ut_launcherpage/ut_launcherpage.cpp
@@ -45,6 +45,32 @@
 {
 }
 
+void LauncherButton::retranslateUi()
+{
+    return;
+}
+
+bool LauncherButton::isInProgress() const
+{
+    return false;
+}
+
+void LauncherButton::setProgressIndicatorTimeout(int)
+{
+}
+
+void LauncherButton::hideProgressIndicator()
+{
+}
+
+void LauncherButton::hideProgressIndicatorIfObscured(const QList<WindowInfo> &)
+{
+}
+
+void LauncherButton::init()
+{
+}
+
 void Ut_LauncherPage::initTestCase()
 {
     static int argc = 1;
@@ -126,7 +152,7 @@
 static QSharedPointer<LauncherButton> createLauncherButton(QString desktopFileName)
 {
     QSharedPointer<LauncherButton> button(new LauncherButton);
-    button.data()->setObjectName(desktopFileName);
+    button->setObjectName(desktopFileName);
     return button;
 }
 
--- tests/ut_launcherpage/ut_launcherpage.pro
+++ tests/ut_launcherpage/ut_launcherpage.pro
@@ -7,6 +7,7 @@
 # unit test and unit
 SOURCES += \
     ut_launcherpage.cpp \
+    $$SRCDIR/launcheraction.cpp \
     $$SRCDIR/launcherpage.cpp
 
 # unit test and unit
@@ -17,6 +18,7 @@
 # service classes
 HEADERS += $$SRCDIR/launcherpagemodel.h \
            $$SRCDIR/launcherbuttonmodel.h \
+           $$SRCDIR/launcheraction.h \
            $$SRCDIR/launcherbutton.h
 
 # service sources
--- tests/ut_launcherpageview/ut_launcherpageview.cpp
+++ tests/ut_launcherpageview/ut_launcherpageview.cpp
@@ -24,10 +24,13 @@
 #include "launcherpagemodel.h"
 #include "launcherpagestyle.h"
 #include "launcher.h"
+#include "launcheraction_stub.h"
 #include "launcherbutton_stub.h"
 #include "homeapplication_stub.h"
 #include "mainwindow_stub.h"
 #include "launcherpageview.h"
+#include "windowinfo_stub.h"
+#include "x11wrapper_stub.h"
 
 // MSceneWindow stubs
 int showWindowCount = 0;
@@ -67,28 +70,105 @@
     controller->setView(view);
     showWindowCount = 0;
     hideWindowCount = 0;
+    connect(this, SIGNAL(updateDataRequested(const QList<const char *>&)),
+            view, SLOT(updateData(const QList<const char *>&)));
 }
 
 void Ut_LauncherPageView::cleanup()
 {
-    delete controller;
+    if (controller != NULL) {
+        delete controller;
+        controller = NULL;
+    }
+    gLauncherButtonStub->stubReset();
 }
 
 void Ut_LauncherPageView::testAddButtonsToPage()
 {
     QSharedPointer<LauncherButton> widget1(new LauncherButton);
     QSharedPointer<LauncherButton> widget2(new LauncherButton);
+    QSharedPointer<LauncherButton> widget3(new LauncherButton);
+    QSharedPointer<LauncherButton> widget4(new LauncherButton);
     LauncherPageModel::LauncherButtonList widgets;
     widgets.append(widget1);
+    controller->model()->setLauncherButtons(widgets);
+    // add several widgets so that the order is tested better
     widgets.append(widget2);
+    widgets.append(widget3);
+    widgets.append(widget4);
     controller->model()->setLauncherButtons(widgets);
 
     MLayout* mainLayout = dynamic_cast<MLayout *>(controller->layout());
     QVERIFY(mainLayout != NULL);
 
+    QCOMPARE(mainLayout->count(), widgets.count());
+    for (int i = 0; i < mainLayout->count(); i++) {
+        QCOMPARE(mainLayout->itemAt(i), widgets.at(i).data());
+    }
+}
+
+void Ut_LauncherPageView::testRemovingButtonFromLayout()
+{
+    QSharedPointer<LauncherButton> widget1(new LauncherButton);
+    QSharedPointer<LauncherButton> widget2(new LauncherButton);
+    LauncherPageModel::LauncherButtonList widgets;
+    widgets.append(widget1);
+    widgets.append(widget2);
+    controller->model()->setLauncherButtons(widgets);
+
+    MLayout* mainLayout = dynamic_cast<MLayout *>(controller->layout());
+
+    widgets.removeOne(widget1);
+    controller->model()->setLauncherButtons(widgets);
+
+    QCOMPARE(mainLayout->count(), 1);
+    QCOMPARE(mainLayout->itemAt(0), widget2.data());
+    // verify that button destructor has not been called when there is still ref in QSharedPointer
+    QCOMPARE(gLauncherButtonStub->stubCallCount("~LauncherButton"), 0);
+}
+
+void Ut_LauncherPageView::testRemovingButtonFromLayoutInDestructor()
+{
+    QSharedPointer<LauncherButton> widget(new LauncherButton);
+    LauncherPageModel::LauncherButtonList widgets;
+    widgets.append(widget);
+    controller->model()->setLauncherButtons(widgets);
+
+    delete controller;
+    controller = NULL;
+
+    // verify that button destructor has not been called when there is still ref in QSharedPointer
+    QCOMPARE(gLauncherButtonStub->stubCallCount("~LauncherButton"), 0);
+}
+
+void Ut_LauncherPageView::testUpdateData()
+{
+    QSharedPointer<LauncherButton> widget1(new LauncherButton);
+    QSharedPointer<LauncherButton> widget2(new LauncherButton);
+    LauncherPageModel::LauncherButtonList widgets;
+    widgets.append(widget1);
+    widgets.append(widget2);
+    controller->model()->setLauncherButtons(widgets);
+
+    MLayout* mainLayout = dynamic_cast<MLayout *>(controller->layout());
     QCOMPARE(mainLayout->count(), 2);
-    QCOMPARE(mainLayout->itemAt(0), widget1.data());
-    QCOMPARE(mainLayout->itemAt(1), widget2.data());
+    mainLayout->removeItem(widget1.data());
+    mainLayout->removeItem(widget2.data());
+    QCOMPARE(mainLayout->count(), 0);
+
+    QList<const char*> modifications;
+    modifications.append(LauncherPageModel::LauncherButtons);
+    emit updateDataRequested(modifications);
+    QCOMPARE(mainLayout->count(), 2);
+
+    mainLayout->removeItem(widget1.data());
+    mainLayout->removeItem(widget2.data());
+    QCOMPARE(mainLayout->count(), 0);
+
+    QList<const char*> modifications2;
+    modifications.append("does not match");
+    emit updateDataRequested(modifications2);
+    QCOMPARE(mainLayout->count(), 0);
 }
 
 QTEST_APPLESS_MAIN(Ut_LauncherPageView)
--- tests/ut_launcherpageview/ut_launcherpageview.h
+++ tests/ut_launcherpageview/ut_launcherpageview.h
@@ -31,6 +31,8 @@
 {
     Q_OBJECT
 
+signals:
+    void updateDataRequested(const QList<const char *>& modifications);
 private slots:
     // Called before the first testfunction is executed
     void initTestCase();
@@ -43,6 +45,9 @@
 
     // Test cases
     void testAddButtonsToPage();
+    void testRemovingButtonFromLayout();
+    void testRemovingButtonFromLayoutInDestructor();
+    void testUpdateData();
 
 private:
     // MApplication
--- tests/ut_launcherpageview/ut_launcherpageview.pro
+++ tests/ut_launcherpageview/ut_launcherpageview.pro
@@ -14,10 +14,9 @@
     $$SRCDIR/launcherpageview.cpp \
     $$SRCDIR/launcherpage.cpp
 
-# service classes
-SOURCES += ../stubs/stubbase.cpp \
-    $$SRCDIR/windowinfo.cpp
 
+# service classes
+SOURCES += ../stubs/stubbase.cpp
 
 # unit test and unit
 HEADERS += \
--- tests/ut_launcherview/ut_launcherview.cpp
+++ tests/ut_launcherview/ut_launcherview.cpp
@@ -25,6 +25,7 @@
 #include "launcherpage.h"
 #include "launcherbuttonmodel.h"
 #include "launcherbutton_stub.h"
+#include "launcheraction_stub.h"
 #include "launcherdatastore_stub.h"
 #include "homeapplication_stub.h"
 #include "mainwindow_stub.h"
@@ -33,6 +34,8 @@
 #include "mockdatastore.h"
 #include "pagepositionindicatorview.h"
 #include "mpositionindicator.h"
+#include "windowinfo_stub.h"
+#include "x11wrapper_stub.h"
 
 #include "mwidgetcreator.h"
 M_REGISTER_WIDGET(PagedViewport)
@@ -67,6 +70,11 @@
     Q_UNUSED(page)
 }
 
+bool gFocusFirstPageCalled = false;
+void PagedViewport::focusFirstPage() {
+    gFocusFirstPageCalled = true;
+}
+
 /*
 void PagedViewport::updatePageWidth(int width)
 {
@@ -107,11 +115,17 @@
     controller->setView(view);
     showWindowCount = 0;
     hideWindowCount = 0;
+    gFocusFirstPageCalled = false;
+    connect(this, SIGNAL(updateDataRequested(const QList<const char *>&)),
+            view, SLOT(updateData(const QList<const char *>&)));
 }
 
 void Ut_LauncherView::cleanup()
 {
-    delete controller;
+    if (controller != NULL) {
+        delete controller;
+        controller = NULL;
+    }
     delete launcherDataStore;
 }
 
@@ -145,13 +159,14 @@
     QCOMPARE(layout->itemAt(0), page.data());
 }
 
-void Ut_LauncherView::testAddAndRemovePages()
+void Ut_LauncherView::testAddPages()
 {
+    static const int NUM_ITEMS = 10;
     // add two pages
     QList< QSharedPointer<LauncherPage> > pages;
-    for (int iter1 = 0; iter1 < 2; iter1++){
+    for (int iter1 = 0; iter1 < NUM_ITEMS; iter1++){
         QSharedPointer<LauncherPage> page(new LauncherPage());
-        for (int iter2 = 0; iter2 < 10; iter2++) {
+        for (int iter2 = 0; iter2 < NUM_ITEMS; iter2++) {
             QSharedPointer<LauncherButton> button(new LauncherButton());
             page->appendButton(button);
         }
@@ -167,12 +182,88 @@
 
     QGraphicsLayout* layout = pannedWidget->layout();
 
-    QCOMPARE(layout->count(), 2);
+    QCOMPARE(layout->count(), NUM_ITEMS);
+    // verify layout order
+    for (int i = 0; i < NUM_ITEMS; ++i) {
+        QCOMPARE(layout->itemAt(i), pages.at(i).data());
+    }
+}
+
+void Ut_LauncherView::testRemovingPages()
+{
+    QList< QSharedPointer<LauncherPage> > pages;
+    QSharedPointer<LauncherPage> page1(new LauncherPage());
+    QSharedPointer<LauncherPage> page2(new LauncherPage());
+    pages.append(page1);
+    pages.append(page2);
+    controller->model()->setLauncherPages(pages);
 
-    pages.removeAt(1);
+    pages.removeOne(page1);
     controller->model()->setLauncherPages(pages);
 
+    QGraphicsLayout* layout = dynamic_cast<PagedViewport *>(controller->childItems().at(0))->widget()->layout();
     QCOMPARE(layout->count(), 1);
+    // verify that page is not deleted when there is still ref in QSharedPointer
+    QVERIFY(!page1.isNull());
+}
+
+void Ut_LauncherView::testRemovingPagesFromLayoutInDestructor()
+{
+    QSharedPointer<LauncherPage> page(new LauncherPage);
+    LauncherModel::LauncherPageList pages;
+    pages.append(page);
+    controller->model()->setLauncherPages(pages);
+
+    delete controller;
+    controller = NULL;
+    // verify that page is not deleted when there is still ref in QSharedPointer
+    QVERIFY(!page.isNull());
+}
+
+void Ut_LauncherView::testSignalConnection()
+{
+    QVERIFY(disconnect(controller, SIGNAL(focusToFirstPageRequested()), view, SLOT(focusFirstPage())));
+    connect(controller, SIGNAL(focusToFirstPageRequested()), view, SLOT(focusFirstPage()));
+}
+
+void Ut_LauncherView::testFocusFirstPage()
+{
+    // Test that focusToFirstPageRequested() signal goes to correct slot from
+    // which pagedViewport->focusFirstPage() is called
+    controller->setFirstPage();
+    QCOMPARE(gFocusFirstPageCalled, true);
+}
+
+void Ut_LauncherView::testUpdateData()
+{
+    QSharedPointer<LauncherPage> page1(new LauncherPage);
+    QSharedPointer<LauncherPage> page2(new LauncherPage);
+    LauncherModel::LauncherPageList pages;
+    pages.append(page1);
+    pages.append(page2);
+    controller->model()->setLauncherPages(pages);
+
+    MLayout* mainLayout = dynamic_cast<MLayout *>(
+        dynamic_cast<PagedViewport *>(
+            controller->childItems().at(0))->widget()->layout());
+    QCOMPARE(mainLayout->count(), 2);
+    mainLayout->removeItem(page1.data());
+    mainLayout->removeItem(page2.data());
+    QCOMPARE(mainLayout->count(), 0);
+
+    QList<const char*> modifications;
+    modifications.append(LauncherModel::LauncherPages);
+    emit updateDataRequested(modifications);
+    QCOMPARE(mainLayout->count(), 2);
+
+    mainLayout->removeItem(page1.data());
+    mainLayout->removeItem(page2.data());
+    QCOMPARE(mainLayout->count(), 0);
+
+    QList<const char*> modifications2;
+    modifications.append("does not match");
+    emit updateDataRequested(modifications2);
+    QCOMPARE(mainLayout->count(), 0);
 }
 
 QTEST_APPLESS_MAIN(Ut_LauncherView)
--- tests/ut_launcherview/ut_launcherview.h
+++ tests/ut_launcherview/ut_launcherview.h
@@ -33,6 +33,8 @@
 {
     Q_OBJECT
 
+signals:
+    void updateDataRequested(const QList<const char *>& modifications);
 private slots:
     // Called before the first testfunction is executed
     void initTestCase();
@@ -46,7 +48,12 @@
     // Test cases
     void testPagedViewportObjectName();
     void testSetButtons();
-    void testAddAndRemovePages();
+    void testAddPages();
+    void testRemovingPages();
+    void testRemovingPagesFromLayoutInDestructor();
+    void testSignalConnection();
+    void testFocusFirstPage();
+    void testUpdateData();
 
 private:
     // MApplication
@@ -57,6 +64,7 @@
     Launcher *controller;
     LauncherDataStore *launcherDataStore;
     LauncherView *view;
+
 };
 
 #endif
--- tests/ut_launcherview/ut_launcherview.pro
+++ tests/ut_launcherview/ut_launcherview.pro
@@ -20,7 +20,6 @@
 
 # service classes
 SOURCES += ../stubs/stubbase.cpp \
-    $$SRCDIR/windowinfo.cpp \
     $$SRCDIR/pagedpanning.cpp \
     $$SRCDIR/pagepositionindicator.cpp \
     $$SRCDIR/pagepositionindicatorview.cpp
--- tests/ut_pagedpanning/ut_pagedpanning.cpp
+++ tests/ut_pagedpanning/ut_pagedpanning.cpp
@@ -15,7 +15,6 @@
  */
 #include <QtTest/QtTest>
 #include <MApplication>
-#include <QDebug>
 #include <QSignalSpy>
 #include "pagedpanning.h"
 #include "ut_pagedpanning.h"
@@ -142,30 +141,19 @@
 
 void Ut_PagedPanning::testAutoPanning()
 {
-    qreal currentPosition = 300.0;
-    // Do the initial movement so that the subject internal state has some meaning. In this
-    // case is we want the currentPage to be non zero
-    testMovement(m_subject,
-                 11,            // Page count
-                 currentPosition,  // The position where the movement starts
-                 0.0,              // Move amount
-                 300.0 ,           // Where the current position should end up after movement
-                 true,             // Left to right
-                 3);               // Target
-
-    QCOMPARE(currentPosition, 300.0);
-
     qreal velocity = 0;
     qreal acceleration = 0;
     QSignalSpy spy(m_subject, SIGNAL(pageChanged(int)));
 
+    fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
+    m_subject->currentPage = 3;
+    m_subject->setPosition(QPointF(300.0, 0.0));
+
     m_subject->panToPage(0);
 
-    performIntegration(m_subject,
-                       currentPosition, velocity,
-                       acceleration);
+    performIntegration(m_subject);
 
-    QCOMPARE(currentPosition, 0.0);
+    QCOMPARE(m_subject->position().x(), 0.0);
     QList<QVariant> arguments = spy.takeLast();
     QCOMPARE(arguments.at(0).toInt(), 0);
 
@@ -176,11 +164,9 @@
 
     m_subject->panToPage(2);
 
-    performIntegration(m_subject,
-                       currentPosition, velocity,
-                       acceleration);
+    performIntegration(m_subject);
 
-    QCOMPARE(currentPosition, 200.0);
+    QCOMPARE(m_subject->position().x(), 200.0);
     arguments = spy.takeLast();
     QVERIFY(arguments.at(0).toInt() == 2);
 
@@ -188,58 +174,35 @@
 
 void Ut_PagedPanning::testCurrentPageRemainsSameWhenPageCountChanges()
 {
-    qreal currentPosition = 300.0;
-    qreal velocity = 0;
-    qreal pointerSpring = 0;
-    qreal acceleration = 0;
-
     fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
 
-    performMovement(m_subject,
-                    0, // amount to move
-                    true, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration);
-
-    velocity = 0;
-    acceleration = 0;
-    pointerSpring = 0;
-    currentPosition = 300;
-
-    qreal targetPage = 3;
+    qreal currentPosition = 400.0;
+    m_subject->currentPage = 4;
+    m_subject->setPosition(QPointF(currentPosition, 0));
 
     QSignalSpy spy(m_subject, SIGNAL(pageChanged(int)));
-    performMovement(m_subject,
-                    1, // amount to move
-                    true, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration);
 
+    // Change the page count and set the range accordingly
+    m_subject->setPageCount(21);
+    m_subject->setRange(QRectF(0, 0, 2000, 0));
 
-    QCOMPARE(currentPosition , 300.0);
-    QCOMPARE(spy.count(), 1); // make sure the signal was emitted exactly one time
-    QList<QVariant> arguments = spy.takeFirst(); // take the first signal
-    QVERIFY(arguments.at(0).toInt() == targetPage); // Make sure that we are on the right page
+    performIntegration(m_subject);
 
-    velocity = 0;
-    acceleration = 0;
-    pointerSpring = 0;
-    spy.clear();
+    // Neither the position or the page should have changed
+    QCOMPARE(m_subject->position().x(), 400.0);
+    QCOMPARE(spy.count(), 0);
 
-    m_subject->setPageCount(21);
+    // Set the count to be less than the current page and reduce the range
+    m_subject->setPageCount(3);
+    m_subject->setRange(QRectF(0, 0, 200, 0));
 
-    /*
-      When the page count is set the pager requests start from its parent class.
-      As the QTimeline is not running here we simulate the behaviour be calling the
-      integrator our selves.
-    */
-    performIntegration(m_subject,
-                       currentPosition, velocity,
-                       acceleration);
+    performIntegration(m_subject);
 
-    //Now the position should have changed, but the page info signal should reflect the original state
-    QCOMPARE(currentPosition , 150.0);
-    QCOMPARE(spy.count(), 0);
+    // Now we should have ended on the last page
+    QCOMPARE(m_subject->position().x(), 200.0);
+    QCOMPARE(spy.count(), 1);
+    QList<QVariant> arguments = spy.takeFirst();
+    QCOMPARE(arguments.at(0).toInt(), 2);
 }
 
 void Ut_PagedPanning::testSetPageCount()
@@ -250,7 +213,6 @@
     QCOMPARE(spy.count(), 0);
 }
 
-
 void Ut_PagedPanning::testMovement(PagedPanning* pagedPanning,
                                    int pageCount,
                                    qreal currentPosition,
@@ -267,8 +229,10 @@
 
     fillDefaultIntegrationParameters(pagedPanning, pageCount, rangeStart, rangeEnd);
 
-    qreal pageWidth = (rangeEnd-rangeStart)/(qreal)pageCount;
+    qreal pageWidth = (rangeEnd - rangeStart) / qMax(1, pageCount-1);
     pagedPanning->currentPage = currentPosition/pageWidth;
+    pagedPanning->pageWidth = pageWidth;
+    pagedPanning->setPosition(QPointF(currentPosition, 0));
 
     int pageCrossings;
 
@@ -290,13 +254,10 @@
 
     performMovement(pagedPanning,
                     moveAmount, // amount to move
-                    leftToRight, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration);
+                    leftToRight); // left-to-right
 
     QCOMPARE(velocity, 0.0);
-    QCOMPARE(acceleration, 0.0);
-    QCOMPARE(currentPosition, targetPosition);
+    QCOMPARE(pagedPanning->position().x(), targetPosition);
 
     QCOMPARE(spy.count(), pageCrossings);
     if (pageCrossings > 0) {
@@ -309,46 +270,47 @@
 void Ut_PagedPanning::performMovement(PagedPanning* pagedPanning,
                                       qreal moveAmount,
                                       bool leftToRight,
-                                      qreal &position,
-                                      qreal &velocity,
-                                      qreal &pointerSpring,
-                                      qreal &acceleration,
                                       qreal speed)
 
 {
     int i = 0;
+    qreal movePosition = 0;
     bool pointerPressControl = true;
-    while (pointerPressControl || velocity != 0.0) {
-        if (i++ < moveAmount) {
-            pointerSpring += leftToRight ? speed : -speed;
-        } else {
+
+    pagedPanning->pointerPress(QPointF(movePosition, 0));
+
+    while (pointerPressControl || pagedPanning->velocity().x() != 0.0) {
+        if (i++ < moveAmount/speed) {
+            movePosition += leftToRight ? speed : -speed;
+        } else if (pointerPressControl) {
+            pagedPanning->pointerRelease();
             pointerPressControl = false;
-            pointerSpring = 0;
         }
-        pagedPanning->integrateAxis(Qt::Horizontal,
-                                    position,
-                                    velocity,
-                                    acceleration,
-                                    pointerSpring,
-                                    pointerPressControl);
+
+        if (pointerPressControl) {
+            pagedPanning->pointerMove(QPointF(movePosition, 0));
+        }
+
+        // Wait for the timer event
+        while(!QCoreApplication::hasPendingEvents())
+            QTest::qSleep(100);
+
+        QCoreApplication::processEvents();
     }
 }
 
 
-void Ut_PagedPanning::performIntegration(PagedPanning* pagedPanning,
-                                         qreal &position,
-                                         qreal &velocity,
-                                         qreal &acceleration)
+void Ut_PagedPanning::performIntegration(PagedPanning* pagedPanning)
 {
-    qreal pointerSpring = 0.0;
+    QSignalSpy stopSpy(pagedPanning, SIGNAL(panningStopped()));
+
     do {
-        pagedPanning->integrateAxis(Qt::Horizontal,
-                                    position,
-                                    velocity,
-                                    acceleration,
-                                    pointerSpring,
-                                    false);
-    } while (velocity != 0.0);
+        while (!QCoreApplication::hasPendingEvents())
+            QTest::qSleep(100);
+
+        QCoreApplication::processEvents();
+    } while (stopSpy.count() == 0);
+
 }
 
 void Ut_PagedPanning::fillDefaultIntegrationParameters(PagedPanning* pagedPanning, qreal newPageCount, qreal rangeStart, qreal rangeEnd)
@@ -368,45 +330,34 @@
 
 void Ut_PagedPanning::testDragThreshold()
 {
-    qreal velocity = 0;
-    qreal pointerSpring = 0;
-    qreal acceleration = 0;
     qreal currentPosition = 200.0;
 
     fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
 
     m_subject->currentPage = 2;
     m_subject->setDragThreshold(0.2);
+    m_subject->setPosition(QPointF(currentPosition, 0));
 
     QSignalSpy spy(m_subject, SIGNAL(pageChanged(int)));
 
     // Drag the pointer a bit, but don't cross the drag threshold
     performMovement(m_subject,
                     10, // amount to move
-                    true, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration);
+                    true); // left-to-right
 
-    QCOMPARE(currentPosition, 200.0);
+    QCOMPARE(m_subject->position().x(), 200.0);
 
     // The page shouldn't have changed yet
     QCOMPARE(spy.count(), 0);
 
     spy.clear();
 
-    // Let the panning settle
-    performIntegration(m_subject,
-                       currentPosition, velocity,
-                       acceleration);
-
     // Drag the pointer over the drag threshold
     performMovement(m_subject,
                     22, // amount to move
-                    false, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration);
+                    false); // left-to-right
 
-    QCOMPARE(currentPosition, 300.0);
+    QCOMPARE(m_subject->position().x(), 300.0);
 
     QCOMPARE(spy.count(), 1);
     QList<QVariant> arguments = spy.takeLast();
@@ -415,14 +366,12 @@
 
 void Ut_PagedPanning::testVelocityThreshold()
 {
-    qreal velocity = 0;
-    qreal pointerSpring = 0;
-    qreal acceleration = 0;
     qreal currentPosition = 100.0;
 
     fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
 
     m_subject->currentPage = 1;
+    m_subject->setPosition(QPointF(currentPosition, 0));
     m_subject->setVelocityThreshold(10.0);
     m_subject->setPointerSpringK(1.0);
 
@@ -431,11 +380,18 @@
     performMovement(m_subject,
                     1,    // amount to move
                     false, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration,
+                    7.0); // speed under threshold
+
+    // Should end up where started
+    QCOMPARE(m_subject->position().x(), 100.0);
+
+    performMovement(m_subject,
+                    1,    // amount to move
+                    false, // left-to-right
                     11.0); // more speed
 
-    QCOMPARE(currentPosition, 200.0);
+    // Should end up on the next page now
+    QCOMPARE(m_subject->position().x(), 200.0);
 
     QCOMPARE(spy.count(), 1);
     QList<QVariant> arguments = spy.takeLast();
@@ -444,14 +400,12 @@
 
 void Ut_PagedPanning::testSlide()
 {
-    qreal velocity = 0;
-    qreal pointerSpring = 0;
-    qreal acceleration = 0;
     qreal currentPosition = 100.0;
 
     fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
 
     m_subject->currentPage = 1;
+    m_subject->setPosition(QPointF(currentPosition, 0));
     m_subject->setSlidingFriction(0.02);
 
     QSignalSpy spy(m_subject, SIGNAL(pageChanged(int)));
@@ -459,12 +413,10 @@
     performMovement(m_subject,
                     70,    // amount to move
                     false, // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration,
                     4.0); // more speed
 
     // Should have slid over three pages
-    QCOMPARE(currentPosition, 400.0);
+    QCOMPARE(m_subject->position().x(), 400.0);
 
     QCOMPARE(spy.count(), 3);
     QList<QVariant> arguments = spy.takeLast();
@@ -475,12 +427,10 @@
     performMovement(m_subject,
                     70,    // amount to move
                     true,  // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration,
                     10.0); // ridiculous speed
 
     // The view should slide all the way to right
-    QCOMPARE(currentPosition, 0.0);
+    QCOMPARE(m_subject->position().x(), 0.0);
 
     QCOMPARE(spy.count(), 4);
     arguments = spy.takeLast();
@@ -494,8 +444,6 @@
     performMovement(m_subject,
                     30,    // amount to move
                     false,  // left-to-right
-                    currentPosition, velocity, pointerSpring,
-                    acceleration,
                     20.0); // ludicrous speed
 
     // With such a huge swing of a gesture,
@@ -505,4 +453,45 @@
     QCOMPARE(arguments.at(0).toInt(), 1);
 }
 
+void Ut_PagedPanning::testSetRange()
+{
+    qreal currentPosition = 200.0;
+    qreal velocity = 0.0;
+    qreal acceleration = 0.0;
+    qreal pointerSpring = 0.0;
+
+    fillDefaultIntegrationParameters(m_subject, 11, 0, 1000);
+
+    m_subject->currentPage = 2;
+    m_subject->setPosition(QPointF(currentPosition, 0));
+
+    m_subject->setRange(QRectF(0, 0, 550, 0));
+
+    // The position should change immediately in one integration step
+    m_subject->integrateAxis(Qt::Horizontal,
+            currentPosition,
+            velocity,
+            acceleration,
+            pointerSpring,
+            false);
+
+    QCOMPARE(currentPosition, 110.0);
+    QCOMPARE(m_subject->currentPage, 2);
+}
+
+void Ut_PagedPanning::testSetFirstPagePosition()
+{
+    //TODO: add testing of setting position to the right-most page
+    // when using right-to-left layout
+
+    // first set position to be something else than 0
+    m_subject->setPosition(QPointF(200.0, 0.0));
+
+    m_subject->setFirstPagePosition();
+
+    QCOMPARE(m_subject->position().x(), 0.0);
+    QCOMPARE(m_subject->currentPage, 0);
+    QCOMPARE(m_subject->targetPage, 0);
+}
+
 QTEST_APPLESS_MAIN(Ut_PagedPanning)
--- tests/ut_pagedpanning/ut_pagedpanning.h
+++ tests/ut_pagedpanning/ut_pagedpanning.h
@@ -94,15 +94,36 @@
     void testCurrentPageRemainsSameWhenPageCountChanges();
 
     /*!
-     * Tests the setting of the page width
+     * Tests the setting of the page count.
      */
     void testSetPageCount();
 
+    /*!
+     * Tests dragging under and over the drag threshold.
+     */
     void testDragThreshold();
+
+    /*!
+     * Tests small flicks with different velocities.
+     */
     void testVelocityThreshold();
 
+    /*!
+     * Tests sliding over multiple pages.
+     */
     void testSlide();
 
+    /*!
+     * Tests that when the page width changes the view is immediately moved
+     * to the correct position determined by the current page and the new page width.
+     */
+    void testSetRange();
+
+    /*!
+     * Test setting page position to first page
+     */
+    void testSetFirstPagePosition();
+
 private:
     // MApplication
     MApplication *app;
@@ -122,18 +143,11 @@
     void performMovement(PagedPanning* pagedPanning,
 			 qreal moveAmount,
 			 bool leftToRight,
-			 qreal &position,
-			 qreal &velocity,
-			 qreal &pointerSpring,
-			 qreal &acceleration,
                          qreal speed = 1.0);
 
     void fillDefaultIntegrationParameters(PagedPanning* pagedPanning, qreal newPageWidth, qreal rangeStart, qreal rangeEnd);
 
-    void performIntegration(PagedPanning* pagedPanning,
-                            qreal &position,
-                            qreal &velocity,
-                            qreal &acceleration);
+    void performIntegration(PagedPanning* pagedPanning);
 };
 
 #endif
--- tests/ut_pagedviewport/ut_pagedviewport.cpp
+++ tests/ut_pagedviewport/ut_pagedviewport.cpp
@@ -27,6 +27,11 @@
 static uint checkPageCount = 0;
 static uint testPanTargetPage = 0;
 
+void MPannableViewport::setWidget(QGraphicsWidget*)
+{
+
+}
+
 PagedPanning::PagedPanning(QObject* parent) : MPhysics2DPanning(parent),
                                               pageCount_(1),
                                               currentPage(0),
@@ -35,7 +40,6 @@
                                               dragThreshold_(0.5),
                                               pageSnapSpringK_(0.7),
                                               pageSnapFriction_(0.7),
-                                              previousPointerPressed(false),
                                               previousPosition(0),
                                               targetPage(0),
                                               pageWidth(0)
@@ -54,6 +58,12 @@
     emit pageChanged(page);
 }
 
+bool gSetFirstPagePositionCalled = false;
+void PagedPanning::setFirstPagePosition()
+{
+    gSetFirstPagePositionCalled = true;
+}
+
 void PagedPanning::panToCurrentPage()
 {
     emit pageChanged(currentPage);
@@ -95,6 +105,20 @@
 {
 }
 
+void PagedPanning::pointerPress(const QPointF &pos)
+{
+    Q_UNUSED(pos);
+}
+
+void PagedPanning::pointerMove(const QPointF &pos)
+{
+    Q_UNUSED(pos);
+}
+
+void PagedPanning::pointerRelease()
+{
+}
+
 void Ut_PagedViewport::initTestCase()
 {
     static int argc = 1;
@@ -110,6 +134,7 @@
 void Ut_PagedViewport::init()
 {
     m_subject = new PagedViewport(NULL);
+    gSetFirstPagePositionCalled = false;
 }
 
 void Ut_PagedViewport::cleanup()
@@ -144,4 +169,10 @@
     QVERIFY(arguments.at(0).toInt() == 1);
 }
 
+void Ut_PagedViewport::test_focusFirstPage()
+{
+    m_subject->focusFirstPage();
+    QCOMPARE(gSetFirstPagePositionCalled, true);
+}
+
 QTEST_APPLESS_MAIN(Ut_PagedViewport)
--- tests/ut_pagedviewport/ut_pagedviewport.h
+++ tests/ut_pagedviewport/ut_pagedviewport.h
@@ -47,6 +47,8 @@
     // Tests that pageChanged signal is emitted when panToPage
     // is called
     void test_panToPage();
+    // Tests setFirstPagePosition method
+    void test_focusFirstPage();
 
 private:
     // MApplication
--- tests/ut_plaindesktopbackgroundextension/ut_plaindesktopbackgroundextension.cpp
+++ tests/ut_plaindesktopbackgroundextension/ut_plaindesktopbackgroundextension.cpp
@@ -30,33 +30,35 @@
 
 // PlainDesktopBackgroundPixmap stubs
 QPixmap *PlainDesktopBackgroundPixmapConstructorPixmap;
-QPixmap *PlainDesktopBackgroundPixmapConstructorBlurredPixmap;
+QPixmap *PlainDesktopBackgroundPixmapConstructorDefocusedPixmap;
 QString PlainDesktopBackgroundPixmapConstructorName;
 QString PlainDesktopBackgroundPixmapConstructorDefaultName;
 int PlainDesktopBackgroundPixmapConstructorBlurRadius;
+qreal PlainDesktopBackgroundPixmapConstructorBrightness;
 QString PlainDesktopBackgroundPixmapConstructorPixmapName;
-PlainDesktopBackgroundPixmap::PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius) :
+PlainDesktopBackgroundPixmap::PlainDesktopBackgroundPixmap(const QString &name, const QString &defaultName, int blurRadius, qreal brightness) :
         pixmapFromTheme_(NULL)
 {
     PlainDesktopBackgroundPixmapConstructorName = name;
     PlainDesktopBackgroundPixmapConstructorDefaultName = defaultName;
     PlainDesktopBackgroundPixmapConstructorBlurRadius = blurRadius;
+    PlainDesktopBackgroundPixmapConstructorBrightness = brightness;
     pixmapFromFile_ = QSharedPointer<QPixmap>(PlainDesktopBackgroundPixmapConstructorPixmap);
-    blurredPixmap_ = QSharedPointer<QPixmap>(PlainDesktopBackgroundPixmapConstructorBlurredPixmap);
+    defocusedPixmap_ = QSharedPointer<QPixmap>(PlainDesktopBackgroundPixmapConstructorDefocusedPixmap);
     pixmapName_ = PlainDesktopBackgroundPixmapConstructorPixmapName;
 }
 
 PlainDesktopBackgroundPixmap::~PlainDesktopBackgroundPixmap()
 {
     PlainDesktopBackgroundPixmapConstructorPixmap = NULL;
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = NULL;
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = NULL;
 }
 
-void PlainDesktopBackgroundPixmap::createBlurredPixmap()
+void PlainDesktopBackgroundPixmap::createDefocusedPixmap()
 {
 }
 
-QPixmap *PlainDesktopBackgroundPixmap::createBlurredPixmap(const QPixmap &, int)
+QPixmap *PlainDesktopBackgroundPixmap::createDefocusedPixmap(const QPixmap &, int, qreal)
 {
     return NULL;
 }
@@ -66,9 +68,9 @@
     return pixmapFromFile_.data();
 }
 
-const QPixmap *PlainDesktopBackgroundPixmap::blurredPixmap() const
+const QPixmap *PlainDesktopBackgroundPixmap::defocusedPixmap() const
 {
-    return blurredPixmap_.data();
+    return defocusedPixmap_.data();
 }
 
 QString PlainDesktopBackgroundPixmap::pixmapName() const
@@ -252,7 +254,7 @@
     updateCalled = false;
     currentOrientationAngle = M::Angle0;
     PlainDesktopBackgroundPixmapConstructorPixmap = NULL;
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = NULL;
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = NULL;
     PlainDesktopBackgroundPixmapConstructorPixmapName.clear();
     MThemePixmapReturnValue = MThemePixmapDefaultValue;
     MGConfItemValueForKey.clear();
@@ -260,11 +262,10 @@
     QTimeLineState = QTimeLine::NotRunning;
     QPainterDrawPixmapTargetRect = QRectF();
     extension = new PlainDesktopBackgroundExtension;
-    connect(this, SIGNAL(setBlurFactor(qreal)), extension, SLOT(setBlurFactor(qreal)));
+    connect(this, SIGNAL(setDefocusFactor(qreal)), extension, SLOT(setDefocusFactor(qreal)));
     connect(this, SIGNAL(updateLandscapePixmap()), extension, SLOT(updateLandscapePixmap()));
     connect(this, SIGNAL(updatePortraitPixmap()), extension, SLOT(updatePortraitPixmap()));
     connect(this, SIGNAL(pixmapUpdated()), extension, SLOT(updateDesktop()));
-    connect(this, SIGNAL(setBlurTimeLineDirection(const QList<WindowInfo> &)), extension, SLOT(setBlurTimeLineDirection(const QList<WindowInfo> &)));
 }
 
 void Ut_PlainDesktopBackgroundExtension::cleanup()
@@ -275,12 +276,12 @@
 void Ut_PlainDesktopBackgroundExtension::testInitialize()
 {
     PlainDesktopBackgroundStyle *landscapeStyle = modifiablePlainDesktopBackgroundStyle(M::Landscape);
-    landscapeStyle->setBlurDuration(3);
-    landscapeStyle->setBlurUpdateInterval(4);
+    landscapeStyle->setDefocusDuration(3);
+    landscapeStyle->setDefocusUpdateInterval(4);
 
     QCOMPARE(extension->initialize(""), true);
-    QCOMPARE(QTimeLineDuration, landscapeStyle->blurDuration());
-    QCOMPARE(QTimeLineUpdateInterval, landscapeStyle->blurUpdateInterval());
+    QCOMPARE(QTimeLineDuration, landscapeStyle->defocusDuration());
+    QCOMPARE(QTimeLineUpdateInterval, landscapeStyle->defocusUpdateInterval());
 }
 
 void Ut_PlainDesktopBackgroundExtension::testWidget()
@@ -296,12 +297,12 @@
 
     // Set up the pixmaps
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     const QPixmap *landscapePixmap = PlainDesktopBackgroundPixmapConstructorPixmap;
     emit updateLandscapePixmap();
 
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     const QPixmap *portraitPixmap = PlainDesktopBackgroundPixmapConstructorPixmap;
     emit updatePortraitPixmap();
 
@@ -332,6 +333,7 @@
     PlainDesktopBackgroundStyle *landscapeStyle = modifiablePlainDesktopBackgroundStyle(M::Landscape);
     PlainDesktopBackgroundStyle *portraitStyle = modifiablePlainDesktopBackgroundStyle(M::Portrait);
     landscapeStyle->setBlurRadius(27);
+    landscapeStyle->setBrightness(0.2);
     landscapeStyle->setDefaultBackgroundImage("landscapeDefault");
     portraitStyle->setDefaultBackgroundImage("portraitDefault");
 
@@ -345,20 +347,22 @@
 
     // Set up the pixmaps
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updateLandscapePixmap();
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorName, landscapeName);
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorDefaultName, landscapeStyle->defaultBackgroundImage());
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorBlurRadius, landscapeStyle->blurRadius());
+    QCOMPARE(PlainDesktopBackgroundPixmapConstructorBrightness, landscapeStyle->brightness());
     QVERIFY(updateCalled);
 
     updateCalled = false;
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updatePortraitPixmap();
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorName, portraitName);
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorDefaultName, portraitStyle->defaultBackgroundImage());
     QCOMPARE(PlainDesktopBackgroundPixmapConstructorBlurRadius, landscapeStyle->blurRadius());
+    QCOMPARE(PlainDesktopBackgroundPixmapConstructorBrightness, landscapeStyle->brightness());
     QVERIFY(updateCalled);
 
     MTheme::releaseStyle(landscapeStyle);
@@ -373,13 +377,13 @@
     // Set up the pixmaps
     PlainDesktopBackgroundPixmapConstructorPixmapName = "testPixmap";
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updateLandscapePixmap();
 
     // Set up the pixmaps again so that they fail
     PlainDesktopBackgroundPixmapConstructorPixmapName = "unexpectedPixmap";
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updateLandscapePixmap();
 
     // Check that the GConf key was set to the previous value
@@ -389,62 +393,57 @@
     MGConfItemValueForKey.insert("/desktop/meego/background/landscape/picture_filename", QString());
     PlainDesktopBackgroundPixmapConstructorPixmapName = QString();
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updateLandscapePixmap();
 
     // Check that the GConf key was not set to the previous value
     QCOMPARE(MGConfItemValueForKey.value("/desktop/meego/background/landscape/picture_filename"), QVariant(QString()));
 }
 
-void Ut_PlainDesktopBackgroundExtension::testSetBlurFactor()
+void Ut_PlainDesktopBackgroundExtension::testSetDefocusFactor()
 {
     QCOMPARE(extension->initialize(""), true);
     extension->setDesktopInterface(*this);
 
     // Set up the pixmaps
     PlainDesktopBackgroundPixmapConstructorPixmap = new QPixmap(1, 1);
-    PlainDesktopBackgroundPixmapConstructorBlurredPixmap = new QPixmap(1, 1);
+    PlainDesktopBackgroundPixmapConstructorDefocusedPixmap = new QPixmap(1, 1);
     emit updateLandscapePixmap();
 
     // This should call MDesktopInterface::update() and painting (called by update()) should use the blur factor
     qreal blurFactor = 0.5;
-    emit setBlurFactor(blurFactor);
+    emit setDefocusFactor(blurFactor);
     QVERIFY(updateCalled);
     QCOMPARE(QPainterOpacity, blurFactor);
 
     // Setting the same blur factor again should not result in updates
     updateCalled = false;
-    emit setBlurFactor(blurFactor);
+    emit setDefocusFactor(blurFactor);
     QVERIFY(!updateCalled);
 }
 
-void Ut_PlainDesktopBackgroundExtension::testSetBlurTimeLineDirection()
+void Ut_PlainDesktopBackgroundExtension::testSetDefocused()
 {
-    QList<WindowInfo> emptyWindowList;
-    QList<WindowInfo> fullWindowList;
-    QString title;
-    fullWindowList.append(WindowInfo(title, Window(), XWindowAttributes(), Pixmap()));
-
     // Test that the timeline direction is set and the timeline is resumed
-    emit setBlurTimeLineDirection(fullWindowList);
+    extension->setDefocused(true);
     QCOMPARE(QTimeLineDirection, QTimeLine::Forward);
     QCOMPARE(QTimeLineState, QTimeLine::Running);
 
     // Test that the timeline is resumed if it's not running even if the direction doesn't change
     QTimeLineState = QTimeLine::NotRunning;
-    emit setBlurTimeLineDirection(fullWindowList);
+    extension->setDefocused(true);
     QCOMPARE(QTimeLineDirection, QTimeLine::Forward);
     QCOMPARE(QTimeLineState, QTimeLine::Running);
 
     // Test that the timeline direction is set when it changes and the timeline is resumed
     QTimeLineState = QTimeLine::NotRunning;
-    emit setBlurTimeLineDirection(emptyWindowList);
+    extension->setDefocused(false);
     QCOMPARE(QTimeLineDirection, QTimeLine::Backward);
     QCOMPARE(QTimeLineState, QTimeLine::Running);
 
     // Test that the timeline is resumed if it's not running even if the direction doesn't change
     QTimeLineState = QTimeLine::NotRunning;
-    emit setBlurTimeLineDirection(emptyWindowList);
+    extension->setDefocused(false);
     QCOMPARE(QTimeLineDirection, QTimeLine::Backward);
     QCOMPARE(QTimeLineState, QTimeLine::Running);
 }
--- tests/ut_plaindesktopbackgroundextension/ut_plaindesktopbackgroundextension.h
+++ tests/ut_plaindesktopbackgroundextension/ut_plaindesktopbackgroundextension.h
@@ -50,14 +50,13 @@
     void testDrawBackground();
     void testUpdatePixmaps();
     void testUpdatePixmapsFails();
-    void testSetBlurFactor();
-    void testSetBlurTimeLineDirection();
+    void testSetDefocusFactor();
+    void testSetDefocused();
     void testUpdateDesktop();
     void testUpdateDesktopNoDesktop();
 
 signals:
-    void setBlurTimeLineDirection(const QList<WindowInfo> &windowList);
-    void setBlurFactor(qreal blurFactor);
+    void setDefocusFactor(qreal blurFactor);
     void updateLandscapePixmap();
     void updatePortraitPixmap();
     void pixmapUpdated();
--- tests/ut_plaindesktopbackgroundpixmap/ut_plaindesktopbackgroundpixmap.cpp
+++ tests/ut_plaindesktopbackgroundpixmap/ut_plaindesktopbackgroundpixmap.cpp
@@ -18,10 +18,37 @@
 ****************************************************************************/
 
 #include <QtTest/QtTest>
+#include <QImageReader>
+#include <QGraphicsBlurEffect>
+#include <QGraphicsItem>
 #include <MTheme>
 #include "ut_plaindesktopbackgroundpixmap.h"
 #include "plaindesktopbackgroundpixmap.h"
 
+qreal qGraphicsEffectBlurRadius;
+void QGraphicsBlurEffect::setBlurRadius(qreal blurRadius)
+{
+    qGraphicsEffectBlurRadius = blurRadius;
+}
+
+qreal qGraphicsItemOpacity;
+void QGraphicsItem::setOpacity(qreal opacity)
+{
+    qGraphicsItemOpacity = opacity;
+}
+
+bool qImageReaderCanRead;
+bool QImageReader::canRead() const
+{
+    return qImageReaderCanRead;
+}
+
+QSize qImageReaderSize;
+QSize QImageReader::size() const
+{
+    return qImageReaderSize;
+}
+
 QString QPixmapLoadFileName;
 bool QPixmapLoadReturnValue;
 bool QPixmap::load(const QString & fileName, const char *, Qt::ImageConversionFlags)
@@ -56,28 +83,34 @@
 void Ut_PlainDesktopBackgroundPixmap::init()
 {
     MThemePixmapReturnValue = MThemePixmapDefaultValue;
+    qImageReaderCanRead = true;
+    qImageReaderSize = QSize(50, 50);
+    qGraphicsEffectBlurRadius = 0;
+    qGraphicsItemOpacity = 0;
 }
 
 void Ut_PlainDesktopBackgroundPixmap::cleanup()
 {
 }
 
-void checkBlurredPixmap(const PlainDesktopBackgroundPixmap &pixmap)
+void checkDefocusedPixmap(const PlainDesktopBackgroundPixmap &pixmap)
 {
-    QVERIFY(pixmap.blurredPixmap() != NULL);
-    QCOMPARE(pixmap.pixmap()->size(), pixmap.blurredPixmap()->size());
+    QVERIFY(pixmap.defocusedPixmap() != NULL);
+    QCOMPARE(pixmap.pixmap()->size(), pixmap.defocusedPixmap()->size());
 }
 
 void Ut_PlainDesktopBackgroundPixmap::testConstructingFromFile()
 {
     QPixmapLoadReturnValue = true;
     QString expectedFileName("/tmp/file.png");
-    PlainDesktopBackgroundPixmap pixmap(expectedFileName, "test", 0);
+    PlainDesktopBackgroundPixmap pixmap(expectedFileName, "test", 5, 0.2);
     QCOMPARE(QPixmapLoadFileName, expectedFileName);
     QVERIFY(pixmap.pixmapFromFile_ != NULL);
     QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromFile_.data());
 
-    checkBlurredPixmap(pixmap);
+    checkDefocusedPixmap(pixmap);
+    QCOMPARE(qGraphicsEffectBlurRadius, (qreal)5);
+    QCOMPARE(qGraphicsItemOpacity, 0.2);
 }
 
 void Ut_PlainDesktopBackgroundPixmap::testConstructingFromFileFails()
@@ -87,13 +120,47 @@
     MThemePixmapReturnValue = &expectedPixmap;
     QPixmapLoadReturnValue = false;
 
-    PlainDesktopBackgroundPixmap pixmap("/tmp/file.png", expectedName, 0);
+    PlainDesktopBackgroundPixmap pixmap("/tmp/file.png", expectedName, 0, 0);
+    QCOMPARE(pixmap.pixmapFromFile_.isNull(), true);
+    QCOMPARE(pixmap.pixmapFromTheme_, &expectedPixmap);
+    QCOMPARE(MThemePixmapId, expectedName);
+    QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromTheme_);
+
+    checkDefocusedPixmap(pixmap);
+}
+
+void Ut_PlainDesktopBackgroundPixmap::testConstructingFromFileFailsBecauseCantRead()
+{
+    QString expectedName("test");
+    QPixmap expectedPixmap(50, 50);
+    MThemePixmapReturnValue = &expectedPixmap;
+    QPixmapLoadReturnValue = true;
+    qImageReaderCanRead = false;
+
+    PlainDesktopBackgroundPixmap pixmap("/tmp/file.png", expectedName, 0, 0);
+    QCOMPARE(pixmap.pixmapFromFile_.isNull(), true);
+    QCOMPARE(pixmap.pixmapFromTheme_, &expectedPixmap);
+    QCOMPARE(MThemePixmapId, expectedName);
+    QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromTheme_);
+
+    checkDefocusedPixmap(pixmap);
+}
+
+void Ut_PlainDesktopBackgroundPixmap::testConstructingFromFileFailsBecauseOfSize()
+{
+    QString expectedName("test");
+    QPixmap expectedPixmap(50, 50);
+    MThemePixmapReturnValue = &expectedPixmap;
+    QPixmapLoadReturnValue = true;
+    qImageReaderSize = QSize(5000, 5000);
+
+    PlainDesktopBackgroundPixmap pixmap("/tmp/file.png", expectedName, 0, 0);
     QCOMPARE(pixmap.pixmapFromFile_.isNull(), true);
     QCOMPARE(pixmap.pixmapFromTheme_, &expectedPixmap);
     QCOMPARE(MThemePixmapId, expectedName);
     QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromTheme_);
 
-    checkBlurredPixmap(pixmap);
+    checkDefocusedPixmap(pixmap);
 }
 
 void Ut_PlainDesktopBackgroundPixmap::testConstructingFromTheme()
@@ -102,36 +169,36 @@
     QPixmap expectedPixmap(50, 50);
     MThemePixmapReturnValue = &expectedPixmap;
 
-    PlainDesktopBackgroundPixmap pixmap(expectedName, "default", 0);
+    PlainDesktopBackgroundPixmap pixmap(expectedName, "default", 0, 0);
     QCOMPARE(pixmap.pixmapFromFile_.isNull(), true);
     QCOMPARE(pixmap.pixmapFromTheme_, &expectedPixmap);
     QCOMPARE(MThemePixmapId, expectedName);
     QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromTheme_);
 
-    // The blurred pixmap creation should have succeeded so pixmapRequestsFinished() signals should not be listened
-    QCOMPARE(disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createBlurredPixmap())), false);
-    checkBlurredPixmap(pixmap);
+    // The defocused pixmap creation should have succeeded so pixmapRequestsFinished() signals should not be listened
+    QCOMPARE(disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createDefocusedPixmap())), false);
+    checkDefocusedPixmap(pixmap);
 }
 
 void Ut_PlainDesktopBackgroundPixmap::testConstructingFromThemeIsDelayed()
 {
     QPixmap brokenPixmap(-1, -1);
     MThemePixmapReturnValue = &brokenPixmap;
-    PlainDesktopBackgroundPixmap pixmap("test", "default", 0);
+    PlainDesktopBackgroundPixmap pixmap("test", "default", 0, 0);
     QSignalSpy spy(&pixmap, SIGNAL(pixmapUpdated()));
 
-    // The blurred pixmap creation should have failed so pixmapRequestsFinished() signals should be listened
-    QCOMPARE(disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createBlurredPixmap())), true);
-    QCOMPARE(pixmap.blurredPixmap(), (QPixmap *)NULL);
+    // The defocused pixmap creation should have failed so pixmapRequestsFinished() signals should be listened
+    QCOMPARE(disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createDefocusedPixmap())), true);
+    QCOMPARE(pixmap.defocusedPixmap(), (QPixmap *)NULL);
     QCOMPARE(spy.count(), 0);
 
     // If the pixmap becomes available the blur should be executed
     QPixmap validPixmap(50, 50);
     pixmap.pixmapFromTheme_ = &validPixmap;
-    connect(this, SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createBlurredPixmap()));
+    connect(this, SIGNAL(pixmapRequestsFinished()), &pixmap, SLOT(createDefocusedPixmap()));
     emit pixmapRequestsFinished();
     QCOMPARE(spy.count(), 1);
-    checkBlurredPixmap(pixmap);
+    checkDefocusedPixmap(pixmap);
 }
 
 void Ut_PlainDesktopBackgroundPixmap::testConstructingFromEmptyName()
@@ -140,13 +207,13 @@
     QPixmap expectedPixmap(50, 50);
     MThemePixmapReturnValue = &expectedPixmap;
 
-    PlainDesktopBackgroundPixmap pixmap("", expectedName, 0);
+    PlainDesktopBackgroundPixmap pixmap("", expectedName, 0, 0);
     QCOMPARE(pixmap.pixmapFromFile_.isNull(), true);
     QCOMPARE(pixmap.pixmapFromTheme_, &expectedPixmap);
     QCOMPARE(MThemePixmapId, expectedName);
     QCOMPARE(pixmap.pixmap(), pixmap.pixmapFromTheme_);
 
-    checkBlurredPixmap(pixmap);
+    checkDefocusedPixmap(pixmap);
 }
 
 QTEST_MAIN(Ut_PlainDesktopBackgroundPixmap)
--- tests/ut_plaindesktopbackgroundpixmap/ut_plaindesktopbackgroundpixmap.h
+++ tests/ut_plaindesktopbackgroundpixmap/ut_plaindesktopbackgroundpixmap.h
@@ -39,6 +39,8 @@
     // Test cases
     void testConstructingFromFile();
     void testConstructingFromFileFails();
+    void testConstructingFromFileFailsBecauseCantRead();
+    void testConstructingFromFileFailsBecauseOfSize();
     void testConstructingFromTheme();
     void testConstructingFromThemeIsDelayed();
     void testConstructingFromEmptyName();
--- tests/ut_quicklaunchbar/ut_quicklaunchbar.cpp
+++ tests/ut_quicklaunchbar/ut_quicklaunchbar.cpp
@@ -17,14 +17,14 @@
 **
 ****************************************************************************/
 
+#include <QtTest/QtTest>
 #include "ut_quicklaunchbar.h"
 #include "quicklaunchbar.h"
-#include "launcher_stub.h"
 #include "launcherbutton_stub.h"
+#include "launcheraction_stub.h"
 #include "launcherdatastore_stub.h"
 #include "mockdatastore.h"
-
-#include <QtTest/QtTest>
+#include "windowinfo_stub.h"
 
 void Ut_QuickLaunchBar::initTestCase()
 {
--- tests/ut_quicklaunchbar/ut_quicklaunchbar.pro
+++ tests/ut_quicklaunchbar/ut_quicklaunchbar.pro
@@ -10,7 +10,7 @@
 
 # base classes
 SOURCES += \
-    $$STUBSDIR\stubbase.cpp
+    $$STUBSDIR/stubbase.cpp
 
 # unit test and unit
 HEADERS += \
@@ -22,7 +22,7 @@
     $$SRCDIR/quicklaunchbarmodel.h \
     $$SRCDIR/launcherbutton.h \
     $$SRCDIR/launcherdatastore.h \
-    $$SRCDIR/launcher.h
+    $$SRCDIR/windowinfo.h
 
 DEFINES += APPLICATIONS_DIRECTORY=\'$$quote(\"/tmp/ut_launcher/applications/\")\'
 
--- tests/ut_quicklaunchbarview/ut_quicklaunchbarview.cpp
+++ tests/ut_quicklaunchbarview/ut_quicklaunchbarview.cpp
@@ -22,8 +22,9 @@
 #include "quicklaunchbar.h"
 #include "quicklaunchbarview.h"
 #include "launcherbutton_stub.h"
-#include "launcher_stub.h"
+#include "launcheraction_stub.h"
 #include "launcherdatastore_stub.h"
+#include "windowinfo_stub.h"
 #include "mockdatastore.h"
 #include <QGraphicsLinearLayout>
 
--- tests/ut_quicklaunchbarview/ut_quicklaunchbarview.pro
+++ tests/ut_quicklaunchbarview/ut_quicklaunchbarview.pro
@@ -23,9 +23,9 @@
     $$SRCDIR/quicklaunchbarmodel.h \
     $$SRCDIR/quicklaunchbarstyle.h \
     $$SRCDIR/quicklaunchbar.h \
-    $$SRCDIR/launcher.h \
     $$SRCDIR/launcherbutton.h \
     $$SRCDIR/launcherdatastore.h \
+    $$SRCDIR/windowinfo.h \
 
 DEFINES += APPLICATIONS_DIRECTORY=\'$$quote(\"/tmp/ut_launcher/applications/\")\'
 
--- tests/ut_switcher/ut_switcher.cpp
+++ tests/ut_switcher/ut_switcher.cpp
@@ -17,20 +17,134 @@
 **
 ****************************************************************************/
 #include <QtTest/QtTest>
-#include <MApplication>
 #include <MApplicationPage>
-
 #include <QFocusEvent>
 #include "ut_switcher.h"
 #include "switcher.h"
 #include "switcherbutton.h"
 #include "switcherview.h"
-#include "windowinfo.h"
-#include "x11wrapper_stub.h"
+#include "x11wrapper.h"
 #include "mscenemanager_stub.h"
 #include "mwindow_stub.h"
+#include "homeapplication_stub.h"
+
+static QString gWindowInfoTitle;
+static QMap<Atom, QString> gInternedAtoms;
+static int gTypeOfXSendEvent;
+static Atom gMessageTypeOfXSendEvent;
+static int gFormatOfXSendEvent;
+static Window gWindowOfXSendEvent;
+static Display* gDisplayOfXSendEvent;
+static long gMaskOfXSendEvent;
+static Bool gPropagateFlagOfXSendEvent;
+static long gLongParametersOfXSendEvent[5];
+static const unsigned long WINDOW_ID_FOR_WINDOW_TO_FRONT = 666;
+static const unsigned long WINDOW_ID_FOR_CLOSE_WINDOW = 777;
+static const unsigned long WINDOW_ID_FOR_WINDOW_VISIBLE = 888;
+Atom X11Wrapper::XInternAtom(Display *, const char *name, Bool)
+{
+    Atom returnValue = reinterpret_cast<Atom>(name);
+    gInternedAtoms[returnValue] = QString(name);
+    return returnValue;
+}
+
+int X11Wrapper::XSelectInput(Display *, Window, long)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWindowAttributes(Display *, Window, XWindowAttributes *)
+{
+    return 0;
+}
+
+int X11Wrapper::XGetWindowProperty(Display *, Window, Atom, long, long, Bool, Atom , Atom *, int *, unsigned long *nitems_return, unsigned long *, unsigned char **prop_return)
+{
+    *nitems_return = 1;
+    *prop_return = (unsigned char*)strdup("1");
+    return Success;
+}
+
+int X11Wrapper::XFree(void *data)
+{
+    if (data != NULL) {
+        delete [](unsigned char *)data;
+    }
+    return 0;
+}
+
+Status X11Wrapper::XGetWMName(Display *, Window, XTextProperty *textProperty)
+{
+    std::string::size_type strSize = gWindowInfoTitle.toStdString().length();
+    textProperty->value = new unsigned char[strSize + 1];
+    strncpy((char *)textProperty->value, gWindowInfoTitle.toStdString().c_str(), strSize + 1);
+    return Success;
+}
+
+Status X11Wrapper::XGetTextProperty(Display *, Window, XTextProperty *, Atom)
+{
+    return 0;
+}
+
+XWMHints *X11Wrapper::XGetWMHints(Display *, Window)
+{
+    return 0;
+}
+
+int X11Wrapper::XFreePixmap(Display *, Pixmap)
+{
+    return 0;
+}
+
+Pixmap X11Wrapper::XCompositeNameWindowPixmap(Display *, Window)
+{
+    return 0;
+}
+
+Damage X11Wrapper::XDamageCreate(Display *, Drawable, int)
+{
+    return 0;
+}
+
+void X11Wrapper::XDamageDestroy(Display *, Damage)
+{
+
+}
+
+int X11Wrapper::XSync(Display *, Bool)
+{
+    return 0;
+}
+
+XErrorHandler X11Wrapper::XSetErrorHandler(XErrorHandler)
+{
+    return 0;
+}
+
+Status X11Wrapper::XSendEvent(Display *display, Window,
+                              Bool propagate, long mask, XEvent *event)
+{
+    gTypeOfXSendEvent = event->type;
+    gDisplayOfXSendEvent = display;
+    gMaskOfXSendEvent = mask;
+    gPropagateFlagOfXSendEvent = propagate;
+    if (event->type == ClientMessage) {
+        gFormatOfXSendEvent = event->xclient.format;
+        gMessageTypeOfXSendEvent = event->xclient.message_type;
+        gWindowOfXSendEvent = event->xclient.window;
+        gLongParametersOfXSendEvent[0] = event->xclient.data.l[0];
+        gLongParametersOfXSendEvent[1] = event->xclient.data.l[1];
+        if (gInternedAtoms[gMessageTypeOfXSendEvent] ==
+            QString("_NET_ACTIVE_WINDOW")) {
+            gLongParametersOfXSendEvent[2] = event->xclient.data.l[2];
+        }
+    }
+    return 0;
+}
 
 QMap<SwitcherButton *, Window> g_windowButtonMap;
+QString g_lastSingleShot;
+QString g_singleShotTarget;
 
 // Home stubs
 class Home : public MApplicationPage
@@ -44,10 +158,24 @@
 }
 
 
+MainWindow *g_testMainWindow;
+
+MainWindow::MainWindow()
+{
+}
+
+MainWindow::~MainWindow()
+{
+}
+
+MainWindow *MainWindow::instance(bool)
+{
+    return g_testMainWindow;
+}
+
 // SwitcherButton stubs (used by Switcher)
-SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window, WindowInfo::WindowPriority windowPriority) :
-    MButton(title, parent, new SwitcherButtonModel),
-    priority(windowPriority)
+SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window) :
+    MButton(title, parent, new SwitcherButtonModel)
 {
     g_windowButtonMap[this] = window;
 }
@@ -69,50 +197,116 @@
 {
 }
 
+void SwitcherButton::enterDisplayEvent()
+{
+}
+
+void SwitcherButton::exitDisplayEvent()
+{
+}
+
 void SwitcherButton::prepareGeometryChange()
 {
     QGraphicsItem::prepareGeometryChange();
 }
 
-void SwitcherButton::setGeometry(const QRectF &rect)
+Window SwitcherButton::xWindow()
 {
-    return MButton::setGeometry(rect);
+    return g_windowButtonMap[this];
 }
 
-void SwitcherButton::updateIconGeometry()
+QHash<Window, QString> g_windowTitles;
+
+WindowInfo::WindowInfo(Window window)
 {
-    Ut_Switcher::iconGeometryUpdated.append(this);
+    d = new WindowData;
+    d->window = window;
 }
 
-WindowInfo::WindowPriority SwitcherButton::windowPriority() const
+WindowInfo::WindowInfo()
 {
-    return priority;
+    d = new WindowData;
 }
 
-void SwitcherButton::setWindowPriority(WindowInfo::WindowPriority windowPriority)
+WindowInfo::~WindowInfo()
 {
-    priority = windowPriority;
 }
 
-QList<SwitcherButton *> Ut_Switcher::iconGeometryUpdated;
+const QString& WindowInfo::title() const
+{
+    return g_windowTitles[d->window];
+}
 
-Window SwitcherButton::xWindow()
+Window WindowInfo::window() const
 {
-    return g_windowButtonMap[this];
+    return d->window;
+}
+
+QList<Atom> WindowInfo::types() const
+{
+    return QList<Atom>();
+}
+
+QList<Atom> WindowInfo::states() const
+{
+    return QList<Atom>();
+}
+
+bool operator==(const WindowInfo &wi1, const WindowInfo &wi2)
+{
+    return wi1.window() == wi2.window();
+}
+
+bool WindowInfo::updateWindowTitle()
+{
+    return true;
+}
+
+void WindowInfo::updateWindowProperties()
+{
+}
+
+void QTimer::singleShot(int msec, QObject *receiver, const char *member)
+{
+    Q_UNUSED(msec);
+
+    if( !g_singleShotTarget.isEmpty() ) {
+        QMetaObject::invokeMethod(receiver, g_singleShotTarget.toAscii().data(), Qt::DirectConnection);
+    }
+
+    g_lastSingleShot = QString(member);
 }
 
 void Ut_Switcher::init()
 {
-    Ut_Switcher::iconGeometryUpdated.clear();
+    gInternedAtoms.clear();
+    gTypeOfXSendEvent = 0;
+    gMessageTypeOfXSendEvent = 0;
+    gFormatOfXSendEvent = 0;
+    gWindowOfXSendEvent = 0;
+    gDisplayOfXSendEvent = NULL;
+    gMaskOfXSendEvent = 0;
+    gPropagateFlagOfXSendEvent = TRUE;
+    for (int i = 0;
+         i < sizeof(gLongParametersOfXSendEvent)/sizeof(long); ++i) {
+        gLongParametersOfXSendEvent[i] = 0;
+    }
 
     // Creating a switcher also creates the switcher view
     switcher = new Switcher;
     switcher->setView(new SwitcherView(switcher));
 
     // Connect widget add/remove signals
-    connect(this, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), switcher, SLOT(windowListUpdated(const QList<WindowInfo> &)));
+    connect(this, SIGNAL(windowListUpdated(const QList<WindowInfo> &)), switcher, SLOT(updateWindowList(const QList<WindowInfo> &)));
     connect(this, SIGNAL(windowTitleChanged(Window, QString)), switcher, SLOT(changeWindowTitle(Window, QString)));
-    connect(this, SIGNAL(sizePosChanged(const QSizeF &, const QRectF &, const QPointF &)), switcher, SLOT(viewportSizePosChanged(const QSizeF &, const QRectF &, const QPointF &)));
+
+    connect(this, SIGNAL(windowToFront(Window)),
+            switcher, SLOT(windowToFront(Window)));
+    connect(this, SIGNAL(closeWindow(Window)),
+            switcher, SLOT(closeWindow(Window)));
+    g_lastSingleShot = QString();
+    g_windowTitles.clear();
+    g_singleShotTarget = "updateButtons";
 }
 
 void Ut_Switcher::cleanup()
@@ -126,7 +320,9 @@
     // MApplications must be created manually these days due to theme system changes
     static int argc = 1;
     static char *app_name = (char *)"./ut_switcher";
-    app = new MApplication(argc, &app_name);
+    app = new HomeApplication(argc, &app_name);
+
+    g_testMainWindow = new MainWindow();
 
     mSceneManager = new MSceneManager(NULL, NULL);
     gMWindowStub->stubSetReturnValue("sceneManager", mSceneManager);
@@ -139,6 +335,59 @@
     delete app;
 }
 
+void Ut_Switcher::testConstruction()
+{
+    QVERIFY(disconnect(app,
+                       SIGNAL(windowListUpdated(const QList<WindowInfo> &)),
+                       switcher,
+                       SLOT(updateWindowList(const QList<WindowInfo> &))));
+    connect(app,
+            SIGNAL(windowListUpdated(const QList<WindowInfo> &)),
+            switcher,
+            SLOT(updateWindowList(const QList<WindowInfo> &)));
+    QVERIFY(disconnect(app,
+                       SIGNAL(windowTitleChanged(Window, QString)),
+                       switcher,
+                       SLOT(changeWindowTitle(Window, QString))));
+    connect(app,
+            SIGNAL(windowTitleChanged(Window, QString)),
+            switcher,
+            SLOT(changeWindowTitle(Window, QString)));
+}
+
+static void testXSendEventCommonValues()
+{
+    QCOMPARE(gTypeOfXSendEvent, ClientMessage);
+    QCOMPARE(gDisplayOfXSendEvent, QX11Info::display());
+    QVERIFY(!gPropagateFlagOfXSendEvent);
+    QCOMPARE(gFormatOfXSendEvent, 32);
+}
+
+void Ut_Switcher::testWindowToFront()
+{
+    emit windowToFront(WINDOW_ID_FOR_WINDOW_TO_FRONT);
+    testXSendEventCommonValues();
+    QCOMPARE(gInternedAtoms[gMessageTypeOfXSendEvent],
+             QString("_NET_ACTIVE_WINDOW"));
+    QCOMPARE(gWindowOfXSendEvent, WINDOW_ID_FOR_WINDOW_TO_FRONT);
+    QCOMPARE(gMaskOfXSendEvent, StructureNotifyMask);
+    QCOMPARE(gLongParametersOfXSendEvent[0], 1L);
+    QCOMPARE(gLongParametersOfXSendEvent[1], CurrentTime);
+    QCOMPARE(gLongParametersOfXSendEvent[2], 0L);
+}
+
+void Ut_Switcher::testCloseWindow()
+{
+    emit closeWindow(WINDOW_ID_FOR_CLOSE_WINDOW);
+    testXSendEventCommonValues();
+    QCOMPARE(gInternedAtoms[gMessageTypeOfXSendEvent],
+             QString("_NET_CLOSE_WINDOW"));
+    QCOMPARE(gWindowOfXSendEvent, WINDOW_ID_FOR_CLOSE_WINDOW);
+    QCOMPARE(gMaskOfXSendEvent, SubstructureRedirectMask);
+    QCOMPARE(gLongParametersOfXSendEvent[0], CurrentTime);
+    QCOMPARE(gLongParametersOfXSendEvent[1], (long)QX11Info::appRootWindow(QX11Info::appScreen()));
+}
+
 void Ut_Switcher::testWindowAdding()
 {
     // Add three test windows to the window list
@@ -161,7 +410,7 @@
 
 void Ut_Switcher::testWindowRemoving()
 {
-    // Add three test windows to the window list
+    // Add three test windows to the window list and the desktop window as the last
     QList<WindowInfo> l = createWindowList(3);
 
     // Let the Switcher know about the updated window list
@@ -194,12 +443,9 @@
     emit windowListUpdated(l);
 
     // Change the name of the second window
-    QString title("Test3");
-    XWindowAttributes a;
-    memset(&a, 0, sizeof(XWindowAttributes));
-    l[1] = WindowInfo(title, (Window)l[1].window(), a, (Pixmap)0);
+    g_windowTitles[1] = QString("Test3");
 
-    // Let the Switcher know about the updated window list
+    // Bring home to foreground and update the window list
     emit windowListUpdated(l);
 
     // There should be three items in the switcher model
@@ -243,35 +489,30 @@
 
     // Let the Switcher know about the updated window list
     emit windowListUpdated(l);
-    Ut_Switcher::iconGeometryUpdated.clear();
+
+    // There should be three items in the switcher model
+    QCOMPARE(switcher->model()->buttons().count(), 3);
 
     // Let the Switcher know about a change in panning
     QSizeF viewportSize;
     QRectF pannedRange;
     QPointF pannedPos;
-    emit sizePosChanged(viewportSize, pannedRange, pannedPos);
-
-    // The icon geometry of the three windows should be changed
-    QCOMPARE(iconGeometryUpdated.count(), 3);
-    for (int i = 0; i < 3; i++) {
-        QCOMPARE(l.at(i).window(), iconGeometryUpdated.at(i)->xWindow());
-    }
 }
 
 QList<WindowInfo> Ut_Switcher::createWindowList(int numWindows)
 {
-    XWindowAttributes a;
-    Pixmap p = 0;
-    memset(&a, 0, sizeof(XWindowAttributes));
-
     QList<WindowInfo> l;
+
     for (int i = 0; i < numWindows; i++) {
-        QString title = QString().sprintf("Test%d", i);
-        l.append(WindowInfo(title, (Window)i, a, p));
+        g_windowTitles[i] = QString().sprintf("Test%d", i);
+
+        l.append(WindowInfo(i));
     }
+
     return l;
 }
 
+
 void Ut_Switcher::testWindowOrder()
 {
     // Add three test windows to the window list
@@ -293,7 +534,7 @@
 
     // Create a new list and shuffle its order
     QList<WindowInfo> sl = createWindowList(3);
-    sl.swap(0, 1);
+    sl.swap(1, 2);
 
     // Let the Switcher know about the updated window list
     emit windowListUpdated(sl);
@@ -312,79 +553,22 @@
     }
 }
 
-void Ut_Switcher::testCallWindowAdding()
+void Ut_Switcher::testUpdateDelay()
 {
     // Add three test windows to the window list
     QList<WindowInfo> l = createWindowList(3);
 
-    // Let the Switcher know about the updated window list
-    emit windowListUpdated(l);
-
-    // There should be three items in the switcher model
-    QCOMPARE(switcher->model()->buttons().count(), 3);
-
-    // See that three SwitcherButtons are added to the model with the correct names
-    for (int i = 0; i < 3; i++) {
-        // The button titles should match the window names (Test0, Test1, Test2)
-        SwitcherButton *b = switcher->model()->buttons().at(i).data();
-        QString title = QString().sprintf("Test%d", i);
-        QCOMPARE(b->text(), title);
-    }
-
-    XWindowAttributes a;
-    memset(&a, 0, sizeof(XWindowAttributes));
-    Window w = 3;
-    Pixmap p = 0;
-    QString callTitle("Call");
-
-    // Add a new call window
-    l.insert(1, WindowInfo(callTitle, w, a, p, WindowInfo::Call));
-
-    emit windowListUpdated(l);
-
-    // There should be four items in the switcher model
-    QCOMPARE(switcher->model()->buttons().count(), 4);
-
-    // The call window should be the first one
-    QCOMPARE(switcher->model()->buttons().at(0)->text(), QString("Call"));
-
-    // See that three previous the SwitcherButtons are still in the same order
-    for (int i = 1; i < 4; i++) {
-        // The button titles should match the window names (Test0, Test1, Test2)
-        SwitcherButton *b = switcher->model()->buttons().at(i).data();
-        QString title = QString().sprintf("Test%d", i - 1);
-        QCOMPARE(b->text(), title);
-    }
-}
-
-void Ut_Switcher::testCallWindowFromExisistingWindow()
-{
-    // Add three test windows to the window list
-    QList<WindowInfo> l = createWindowList(3);
+    // Prevent immediate update
+    g_singleShotTarget.clear();
 
     // Let the Switcher know about the updated window list
     emit windowListUpdated(l);
 
-    // Take the last window and add it again as a call window
-    WindowInfo lwi = l.takeAt(2);
-    QString title = lwi.title();
-    l.append(WindowInfo(title, lwi.window(), lwi.windowAttributes(), lwi.icon(), WindowInfo::Call));
-
-    emit windowListUpdated(l);
+    // There should be no items in the switcher model yet
+    QCOMPARE(switcher->model()->buttons().count(), 0);
 
-    // There should be three items in the switcher model
-    QCOMPARE(switcher->model()->buttons().count(), 3);
-
-    // The last window should now be the first one
-    QCOMPARE(switcher->model()->buttons().at(0)->text(), QString("Test2"));
-
-    // See that the rest of the SwitcherButtons are in the right order
-    for (int i = 1; i < 3; i++) {
-        // The button titles should match the window names (Test0, Test1, Test2)
-        SwitcherButton *b = switcher->model()->buttons().at(i).data();
-        QString title = QString().sprintf("Test%d", i - 1);
-        QCOMPARE(b->text(), title);
-    }
+    // But the update should have been scheduled
+    QVERIFY(g_lastSingleShot.contains("updateButtons"));
 }
 
 QTEST_APPLESS_MAIN(Ut_Switcher)
--- tests/ut_switcher/ut_switcher.h
+++ tests/ut_switcher/ut_switcher.h
@@ -30,6 +30,25 @@
 class QRectF;
 class QPointF;
 
+class MainWindow : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    MainWindow();
+    ~MainWindow();
+
+    MainWindow *instance(bool);
+
+    void exitDisplay();
+
+signals:
+
+    void displayExited();
+};
+
+
 class Ut_Switcher : public QObject
 {
     Q_OBJECT
@@ -44,12 +63,9 @@
     QList<WindowInfo> createWindowList(int numWindows);
 
 signals:
-    // Signal for updating the window list
+    void windowToFront(Window window);
+    void closeWindow(Window window);
     void windowListUpdated(const QList<WindowInfo> &windowList);
-
-    // Signal for panning
-    void sizePosChanged(const QSizeF &viewportSize, const QRectF &pannedRange, const QPointF &pannedPos);
-
     void windowTitleChanged(Window window, const QString &title);
 
 private slots:
@@ -65,6 +81,15 @@
     // Executed once after last test case
     void cleanupTestCase();
 
+    // Test that the constructor connects proper signals
+    void testConstruction();
+
+    // Test bringing windows to front
+    void testWindowToFront();
+
+    // Test bringing windows to front
+    void testCloseWindow();
+
     // Test adding windows
     void testWindowAdding();
 
@@ -82,11 +107,8 @@
     // Test window ordering
     void testWindowOrder();
 
-    // Test call window priority
-    void testCallWindowAdding();
-
-    // Test call window priority
-    void testCallWindowFromExisistingWindow();
+    // Test that the Switcher update is delayed when launching new applications
+    void testUpdateDelay();
 
 private:
     MSceneManager *mSceneManager;
--- tests/ut_switcher/ut_switcher.pro
+++ tests/ut_switcher/ut_switcher.pro
@@ -20,9 +20,7 @@
 # service classes
 SOURCES += \
     $$SRCDIR/switcherview.cpp \
-    $$SRCDIR/windowinfo.cpp \
-    $$SRCDIR/mainwindow.cpp \
-       ../stubs/stubbase.cpp \
+    ../stubs/stubbase.cpp \
     $$SRCDIR/pagepositionindicatorview.cpp \
     $$SRCDIR/pagepositionindicator.cpp
 
@@ -39,12 +37,12 @@
     $$SRCDIR/switcherbutton.h \
     $$SRCDIR/switcherbuttonstyle.h \
     $$SRCDIR/switcherbuttonmodel.h \
+    $$SRCDIR/homeapplication.h \
     $$SRCDIR/pagedviewport.h \
     $$SRCDIR/pagedviewportstyle.h \
     $$SRCDIR/pagedviewportview.h \
     $$SRCDIR/pagedpanning.h \
     $$SRCDIR/windowinfo.h \
-    $$SRCDIR/mainwindow.h \
     $$SRCDIR/pagepositionindicatorview.h \
     $$SRCDIR/pagepositionindicatorstyle.h \
     $$SRCDIR/pagepositionindicator.h \
--- tests/ut_switcherbutton/ut_switcherbutton.cpp
+++ tests/ut_switcherbutton/ut_switcherbutton.cpp
@@ -24,9 +24,10 @@
 #include <MSceneManager>
 #include <cstring>
 #include <QSharedPointer>
+#include "windowinfo_stub.h"
 
 #define TEST_ANY_OTHER_ATOM 1
-#define TEST_NET_WM_ICON_GEOMETRY_ATOM 303
+#define TEST_MEEGOTOUCH_VISIBLE_IN_SWITCHER_ATOM 304
 
 // QCoreApplication stubs to avoid crashing in processEvents()
 QStringList QCoreApplication::arguments()
@@ -41,7 +42,11 @@
 
 Atom X11Wrapper::XInternAtom(Display *, const char *atom_name, Bool)
 {
-    return strcmp(atom_name, "_NET_WM_ICON_GEOMETRY") == 0 ? TEST_NET_WM_ICON_GEOMETRY_ATOM : TEST_ANY_OTHER_ATOM;
+    if (strcmp(atom_name, "_MEEGOTOUCH_VISIBLE_IN_SWITCHER") == 0) {
+        return TEST_MEEGOTOUCH_VISIBLE_IN_SWITCHER_ATOM;
+    } else {
+        return TEST_ANY_OTHER_ATOM;
+    }
 }
 
 int X11Wrapper::XChangeProperty(Display *display, Window w, Atom property, Atom type, int format, int mode, unsigned char *data, int nelements)
@@ -156,57 +161,33 @@
     QVERIFY(prepareGeometryChangeCalled);
 }
 
-void Ut_SwitcherButton::testSetGeometry()
+void Ut_SwitcherButton::testSetVisibleInSwitcherProperty()
 {
-    // Verify that the icon position for the window is set properly when the switcher button is moved
-    QGraphicsScene scene;
-    scene.addItem(button);
-    button->model()->setXWindow(3);
-    button->setGeometry(QRectF(25, 25, 50, 50));
-
-    // Get the expected icon position
-    QRectF iconPosition = button->boundingRect();
-    iconPosition.moveTo(button->mapToScene(0, 0));
-
-    // Update the icon geometry
-    scene.removeItem(button);
+    // Set window visible in the Switcher
+    button->setVisibleInSwitcherProperty(true);
 
-    // XChangeProperty should be called for the window of the button and _NET_WM_ICON_GEOMETRY property should be filled with 4 32-bit values which should contain the icon geometry
+    // Check correct values passed to X11Wrapper::XChangeProperty()
     QCOMPARE(Ut_SwitcherButton::xChangePropertyWindow, button->xWindow());
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyProperty, (Atom)TEST_NET_WM_ICON_GEOMETRY_ATOM);
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyFormat, 32);
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyNElements, 4);
-    unsigned int *iconGeometry = (unsigned int *)xChangePropertyData;
-    QCOMPARE(iconGeometry[0], (unsigned int)iconPosition.x());
-    QCOMPARE(iconGeometry[1], (unsigned int)iconPosition.y());
-    QCOMPARE(iconGeometry[2], (unsigned int)iconPosition.width());
-    QCOMPARE(iconGeometry[3], (unsigned int)iconPosition.height());
-}
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyProperty, (Atom)TEST_MEEGOTOUCH_VISIBLE_IN_SWITCHER_ATOM);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyFormat, 8);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyMode, PropModeReplace);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyType, XA_CARDINAL);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyNElements, 1);
 
-void Ut_SwitcherButton::testUpdateIconGeometry()
-{
-    // Verify that the icon position for the window is set properly when the switcher button is moved
-    QGraphicsScene scene;
-    scene.addItem(button);
-    button->model()->setXWindow(3);
-    button->setGeometry(QRectF(25, 25, 50, 50));
+    unsigned char *data = (unsigned char *)xChangePropertyData;
+    QVERIFY(data[0] == 1);
 
-    // Get the expected icon position
-    QRectF iconPosition = button->boundingRect();
-    iconPosition.moveTo(button->mapToScene(0, 0));
+    // Set window not visible in the Switcher
+    button->setVisibleInSwitcherProperty(false);
 
-    // XChangeProperty should be called for the window of the button and _NET_WM_ICON_GEOMETRY property should be filled with 4 32-bit values which should contain the icon geometry
+    // Check correct values passed to X11Wrapper::XChangeProperty()
     QCOMPARE(Ut_SwitcherButton::xChangePropertyWindow, button->xWindow());
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyProperty, (Atom)TEST_NET_WM_ICON_GEOMETRY_ATOM);
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyFormat, 32);
-    QCOMPARE(Ut_SwitcherButton::xChangePropertyNElements, 4);
-    unsigned int *iconGeometry = (unsigned int *)xChangePropertyData;
-    QCOMPARE(iconGeometry[0], (unsigned int)iconPosition.x());
-    QCOMPARE(iconGeometry[1], (unsigned int)iconPosition.y());
-    QCOMPARE(iconGeometry[2], (unsigned int)iconPosition.width());
-    QCOMPARE(iconGeometry[3], (unsigned int)iconPosition.height());
-
-    scene.removeItem(button);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyProperty, (Atom)TEST_MEEGOTOUCH_VISIBLE_IN_SWITCHER_ATOM);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyFormat, 8);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyMode, PropModeReplace);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyType, XA_CARDINAL);
+    QCOMPARE(Ut_SwitcherButton::xChangePropertyNElements, 1);
+    QVERIFY(data[0] == 0);
 }
 
 QTEST_APPLESS_MAIN(Ut_SwitcherButton)
--- tests/ut_switcherbutton/ut_switcherbutton.h
+++ tests/ut_switcherbutton/ut_switcherbutton.h
@@ -78,10 +78,8 @@
     void testSwitchToWindow();
     void testClose();
     void testPrepareGeometryChange();
-    // Verify that the icon position for the window is set properly when the switcher button is moved
-    void testSetGeometry();
-    // Verify that the icon position for the window is set properly when requested
-    void testUpdateIconGeometry();
+    // Test that X11 properties are set correctly if visible in switcher
+    void testSetVisibleInSwitcherProperty();
 };
 
 #endif //_UT_APPLETBUTTON_
--- tests/ut_switcherbuttonview/ut_switcherbuttonview.cpp
+++ tests/ut_switcherbuttonview/ut_switcherbuttonview.cpp
@@ -18,31 +18,53 @@
 ****************************************************************************/
 #include "ut_switcherbuttonview.h"
 
-#include <QGLContext>
 #include <MScalableImage>
 #include <MCancelEvent>
-#include <MSceneManager>
+#include "mscenemanager_stub.h"
 #include <MScene>
+#include <MLabel>
 #include "mainwindow_stub.h"
 #include "homeapplication_stub.h"
+#include "windowinfo_stub.h"
 
 bool Ut_SwitcherButtonView::timerImmediateTimeout = false;
+bool Ut_SwitcherButtonView::timerStarted = false;
 MainWindow *Ut_SwitcherButtonView::mainWindow = NULL;
 
+const int NAVIGATION_BAR_HEIGHT = 100;
+
+#define TEST_ANY_OTHER_ATOM 1
+#define TEST_NET_WM_ICON_GEOMETRY_ATOM 303
+
 // QCoreApplication stubs to avoid crashing in processEvents()
 QStringList QCoreApplication::arguments()
 {
     return QStringList();
 }
 
-// X11Wrapper stubs (used by SwitcherButton)
-Atom X11Wrapper::XInternAtom(Display *, const char *, Bool)
+// X11Wrapper stubs (used by SwitcherButtonView)
+Atom X11Wrapper::XInternAtom(Display *, const char *atom_name, Bool)
 {
-    return 1;
+    if (strcmp(atom_name, "_NET_WM_ICON_GEOMETRY") == 0) {
+        return TEST_NET_WM_ICON_GEOMETRY_ATOM;
+    } else {
+        return TEST_ANY_OTHER_ATOM;
+    }
 }
 
-int X11Wrapper::XChangeProperty(Display *, Window, Atom, Atom, int, int, unsigned char *, int)
+int X11Wrapper::XChangeProperty(Display *display, Window w, Atom property, Atom type, int format, int mode, unsigned char *data, int nelements)
 {
+    Ut_SwitcherButtonView::xChangePropertyDisplay = display;
+    Ut_SwitcherButtonView::xChangePropertyWindow = w;
+    Ut_SwitcherButtonView::xChangePropertyProperty = property;
+    Ut_SwitcherButtonView::xChangePropertyType = type;
+    Ut_SwitcherButtonView::xChangePropertyFormat = format;
+    Ut_SwitcherButtonView::xChangePropertyMode = mode;
+    Ut_SwitcherButtonView::xChangePropertyNElements = nelements;
+
+    if (data != NULL) {
+        memcpy(Ut_SwitcherButtonView::xChangePropertyData, data, nelements * format / 8);
+    }
     return 0;
 }
 
@@ -51,51 +73,25 @@
 {
 }
 
-// MGLRenderer stubs (used by SwitcherButton)
-#ifdef M_USE_OPENGL
-MGLRenderer::MGLRenderer() : d_ptr(0)
-{
-}
-
-MGLRenderer::~MGLRenderer()
-{
-}
-
-MGLRenderer *MGLRenderer::instance()
-{
-    static MGLRenderer mGLRenderer;
-    return &mGLRenderer;
-}
-
-quint32 MGLRenderer::bindX11Pixmap(Pixmap pixmap)
-{
-    Q_UNUSED(pixmap);
-    return 1;
-}
-
-void MGLRenderer::unbindX11Pixmap(Pixmap pixmap)
-{
-    Q_UNUSED(pixmap);
-}
-
-void MGLRenderer::drawTexture(const QTransform &transform, quint32 texId, const QSizeF &size, qreal opacity,
-                                bool inverted)
-{
-    Q_UNUSED(transform);
-    Q_UNUSED(texId);
-    Q_UNUSED(size);
-    Q_UNUSED(opacity);
-    Q_UNUSED(inverted);
-}
-#endif
-
 // X stubs (used by SwitcherButton)
 QList<Pixmap> Ut_SwitcherButtonView::allocatedPixmaps;
 Pixmap Ut_SwitcherButtonView::lastPixmap;
 bool Ut_SwitcherButtonView::xCompositeNameWindowPixmapCausesBadMatch = false;
 XErrorHandler Ut_SwitcherButtonView::xErrorHandler = NULL;
+Display *Ut_SwitcherButtonView::xChangePropertyDisplay;
+Window Ut_SwitcherButtonView::xChangePropertyWindow;
+Atom Ut_SwitcherButtonView::xChangePropertyProperty;
+Atom Ut_SwitcherButtonView::xChangePropertyType;
+int Ut_SwitcherButtonView::xChangePropertyFormat;
+int Ut_SwitcherButtonView::xChangePropertyMode;
+unsigned char Ut_SwitcherButtonView::xChangePropertyData[16];
+int Ut_SwitcherButtonView::xChangePropertyNElements;
 bool Ut_SwitcherButtonView::damageCreated = false;
 unsigned long Ut_SwitcherButtonView::damageHandle = 0;
+Display *Ut_SwitcherButtonView::damageDisplay = NULL;
+bool Ut_SwitcherButtonView::damageSubtracted = false;
+unsigned long Ut_SwitcherButtonView::damageSubtractHandle = NULL;
+Display *Ut_SwitcherButtonView::damageSubtractDisplay = NULL;
 
 XErrorHandler X11Wrapper::XSetErrorHandler(XErrorHandler handler)
 {
@@ -122,10 +118,11 @@
     return Ut_SwitcherButtonView::allocatedPixmaps.removeOne(pixmap) ? 0 : BadPixmap;
 }
 
-Damage X11Wrapper::XDamageCreate(Display *, Drawable drawable, int)
+Damage X11Wrapper::XDamageCreate(Display *dpy, Drawable drawable, int)
 {
     Ut_SwitcherButtonView::damageCreated = true;
     Ut_SwitcherButtonView::damageHandle = drawable;
+    Ut_SwitcherButtonView::damageDisplay = dpy;
     return Ut_SwitcherButtonView::damageHandle;
 }
 
@@ -142,6 +139,13 @@
     return 0;
 }
 
+void X11Wrapper::XDamageSubtract(Display *dpy, Damage damage, XserverRegion, XserverRegion)
+{
+    Ut_SwitcherButtonView::damageSubtracted = true;
+    Ut_SwitcherButtonView::damageSubtractHandle = damage;
+    Ut_SwitcherButtonView::damageSubtractDisplay = dpy;
+}
+
 // QTimeLine stubs (used by SwitcherButton)
 void QTimeLine::start()
 {
@@ -174,6 +178,26 @@
     Ut_SwitcherButtonView::painterTextOpacity = Ut_SwitcherButtonView::painterOpacity;
 }
 
+QRectF Ut_SwitcherButtonView::drawPixmapRect;
+QRectF Ut_SwitcherButtonView::drawPixmapSourceRect;
+void QPainter::drawPixmap(const QRectF &targetRect, const QPixmap &, const QRectF &sourceRect)
+{
+    Ut_SwitcherButtonView::drawPixmapRect = targetRect;
+    Ut_SwitcherButtonView::drawPixmapSourceRect = sourceRect;
+}
+
+int Ut_SwitcherButtonView::returnedPixmapWidth = 180;
+int QPixmap::width() const
+{
+    return Ut_SwitcherButtonView::returnedPixmapWidth;
+}
+
+int Ut_SwitcherButtonView::returnedPixmapHeight = 120;
+int QPixmap::height() const
+{
+    return Ut_SwitcherButtonView::returnedPixmapHeight;
+}
+
 bool Ut_SwitcherButtonView::viewUpdateCalled;
 void MWidgetView::update(const QRectF &)
 {
@@ -209,26 +233,6 @@
 {
 }
 
-void TestSwitcherButtonView::emulateCloseButtonClick()
-{
-    controller->close();
- }
-
-void TestSwitcherButtonView::emulateButtonClick()
-{
-    QGraphicsSceneMouseEvent event;
-    QPointF p = iconRect().center();
-    event.setPos(p);
-    event.setScenePos(p);
-    mousePressEvent(&event);
-    mouseReleaseEvent(&event);
-}
-
-void TestSwitcherButtonView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *item) const
-{
-    SwitcherButtonView::drawContents(painter, item);
-}
-
 // Test home application
 class TestHomeApplication : public HomeApplication
 {
@@ -248,20 +252,25 @@
 }
 
 // QTimer stubs (used by Ut_SwitcherButtonView)
-void QTimer::start(int msec)
+void QTimer::start(int)
 {
-    Q_UNUSED(msec);
+    start();
+}
 
+void QTimer::start()
+{
     if (Ut_SwitcherButtonView::timerImmediateTimeout) {
         emit timeout();
     }
 
     id = 0;
+    Ut_SwitcherButtonView::timerStarted = true;
 }
 
 void QTimer::stop()
 {
     id = -1;
+    Ut_SwitcherButtonView::timerStarted = false;
 }
 
 // QPixmap stubs (used by SwitcherButtonView)
@@ -288,6 +297,7 @@
     QCoreApplication::processEvents();
 
     timerImmediateTimeout = false;
+    timerStarted = false;
     allocatedPixmaps.clear();
     lastPixmap = 0;
     xCompositeNameWindowPixmapCausesBadMatch = false;
@@ -297,6 +307,11 @@
     painterText.clear();
     painterTextOpacity = 0;
     viewUpdateCalled = false;
+    damageDisplay = NULL;
+    damageSubtracted = false;
+    damageSubtractHandle = NULL;
+    damageSubtractDisplay = NULL;
+
 }
 
 void Ut_SwitcherButtonView::cleanup()
@@ -323,18 +338,6 @@
     delete app;
 }
 
-void Ut_SwitcherButtonView::testMousePressRelease()
-{
-    // The MButton signals and the windowToFront signal are interesting
-    QSignalSpy windowToFrontSpy(button, SIGNAL(windowToFront(Window)));
-
-    // Click the button
-    m_subject->emulateButtonClick();
-
-    // Check that windowToFront were emitted
-    QCOMPARE(windowToFrontSpy.count(), 1);
-}
-
 void Ut_SwitcherButtonView::testClosingWithTimeout()
 {
     QSignalSpy closeSpy(button, SIGNAL(closeWindow(Window)));
@@ -346,7 +349,7 @@
     timerImmediateTimeout = true;
 
     // "Click" the close button: check that a closeWindow signal is fired
-    m_subject->emulateCloseButtonClick();
+    button->getView()->closeButton->click();
 
     QCOMPARE(closeSpy.count(), 1);
 
@@ -365,7 +368,8 @@
     button->setGeometry(QRectF(0, 0, 100, 100));
 
     // "Click" the close button: check that a closeWindow signal is fired
-    m_subject->emulateCloseButtonClick();
+    button->getView()->closeButton->click();
+
     QCOMPARE(closeSpy.count(), 1);
 
     // The window close timeout does not occur: check that button is closed and invisible
@@ -391,26 +395,6 @@
     QCOMPARE(damageCreated, true);
 }
 
-void Ut_SwitcherButtonView::testXWindowWithXError()
-{
-    // When a composite error occurs setting an X window ID should cause the error handler to be called and no Damage created
-    xCompositeNameWindowPixmapCausesBadMatch = true;
-    button->model()->setXWindow(1);
-    QCOMPARE(allocatedPixmaps.count(), 0);
-    QCOMPARE(damageCreated, false);
-}
-
-void Ut_SwitcherButtonView::testTextOpacity()
-{
-    QPainter painter;
-    button->model()->setText("test");
-    button->model()->setTextVisible(true);
-    m_subject->modifiableStyle()->setTextOpacity(0.5);
-    m_subject->drawContents(&painter, NULL);
-    QCOMPARE(painterText, QString("test"));
-    QCOMPARE(painterTextOpacity, m_subject->modifiableStyle()->textOpacity());
-}
-
 void Ut_SwitcherButtonView::testViewModeChange()
 {
     QCOMPARE(button->model()->viewMode(), SwitcherButtonModel::Large);
@@ -424,6 +408,24 @@
     }
 }
 
+void Ut_SwitcherButtonView::testApplyingStyle()
+{
+    button->setObjectName("OverviewButton");
+    QCOMPARE(m_subject->closeButton->objectName(), QString("CloseButtonOverview"));
+    QCOMPARE(m_subject->titleLabel->objectName(), QString("SwitcherButtonTitleLabelOverview"));
+
+    button->setObjectName("DetailviewButton");
+    button->model()->setViewMode(SwitcherButtonModel::Large);
+    button->getView()->applyStyle();
+    QVERIFY(m_subject->closeButton->isVisible());
+    QCOMPARE(m_subject->closeButton->objectName(), QString("CloseButtonDetailview"));
+    QCOMPARE(m_subject->titleLabel->objectName(), QString("SwitcherButtonTitleLabelDetailview"));
+
+    button->model()->setViewMode(SwitcherButtonModel::Medium);
+    button->getView()->applyStyle();
+    QVERIFY(!m_subject->closeButton->isVisible());
+}
+
 void Ut_SwitcherButtonView::testDamageEventForKnownDamage()
 {
     // Create a known damage handle
@@ -466,4 +468,156 @@
     QCOMPARE(damageHandle, (unsigned long)0);
 }
 
+void Ut_SwitcherButtonView::testXDamageSubtractWhenDisplayEntered()
+{
+    // The damage is not created unless there is a window
+    button->model()->setXWindow(1);
+
+    button->emitDisplayEntered();
+
+    app->emitDamageEvent(damageHandle, 0, 0, 0, 0);
+
+    QVERIFY(damageSubtracted);
+    QCOMPARE(damageDisplay, damageSubtractDisplay);
+    QCOMPARE(damageHandle, damageSubtractHandle);
+}
+
+void Ut_SwitcherButtonView::testCloseButtonTranslate()
+{
+    const qreal translation = 20.0;
+    QPointF initialPosition = m_subject->closeButton->scenePos();
+
+    m_subject->modifiableStyle()->setCloseButtonHOffset(translation);
+    m_subject->modifiableStyle()->setCloseButtonVOffset(translation);
+
+    m_subject->translateCloseButton();
+
+    QPointF translatedPosition(initialPosition + QPointF(translation, -translation));
+    QCOMPARE(m_subject->closeButton->scenePos(), translatedPosition);
+}
+
+void Ut_SwitcherButtonView::testBoundingRect()
+{
+    const int titleHeight = m_subject->titleLabel->size().height();
+    const QSize thumbnailSize(20, 20);
+    m_subject->modifiableStyle()->setIconSize(thumbnailSize);
+
+    QRectF expectedRect(0, 0, thumbnailSize.width(), titleHeight + thumbnailSize.height());
+    QCOMPARE(m_subject->boundingRect(), expectedRect);
+
+    // check that close button translation doesn't affect the bounding rect
+    const qreal translation = 20.0;
+    m_subject->modifiableStyle()->setCloseButtonHOffset(translation);
+    m_subject->modifiableStyle()->setCloseButtonVOffset(translation);
+    m_subject->translateCloseButton();
+
+    QCOMPARE(m_subject->boundingRect(), expectedRect);
+}
+
+void Ut_SwitcherButtonView::testThumbnailPosition()
+{
+    const int titleHeight = m_subject->titleLabel->size().height();
+
+    QPoint expectedPosition(0, titleHeight);
+    QCOMPARE(m_subject->thumbnailPosition(), expectedPosition);
+}
+
+void Ut_SwitcherButtonView::testSignalConnections()
+{
+    // verify qApp connections
+    QVERIFY(disconnect(qApp, SIGNAL(windowVisibilityChanged(Window)), m_subject, SLOT(windowVisibilityChanged(Window))));
+    QVERIFY(disconnect(qApp, SIGNAL(damageEvent(Qt::HANDLE &, short &, short &, unsigned short &, unsigned short &)), m_subject, SLOT(damageEvent(Qt::HANDLE &, short &, short &, unsigned short &, unsigned short &))));
+
+    QVERIFY(disconnect(button, SIGNAL(displayEntered()), m_subject, SLOT(setOnDisplay())));
+    QVERIFY(disconnect(button, SIGNAL(displayExited()), m_subject, SLOT(unsetOnDisplay())));
+}
+
+const qreal thumbnailStyleWidth = 180.0;
+const qreal thumbnailStyleHeight = 120.0;
+void Ut_SwitcherButtonView::testDrawBackground_data()
+{
+    QTest::addColumn<M::Orientation>("orientation");
+    QTest::addColumn<M::OrientationAngle>("orientationAngle");
+    QTest::addColumn<QRectF>("targetRect");
+    QTest::addColumn<QRectF>("sourceRect");
+
+    QTest::newRow("landscape0") << M::Landscape << M::Angle0
+            << QRectF(0, 0, thumbnailStyleWidth, thumbnailStyleHeight)
+            << QRectF(0, NAVIGATION_BAR_HEIGHT, Ut_SwitcherButtonView::returnedPixmapWidth, Ut_SwitcherButtonView::returnedPixmapHeight - NAVIGATION_BAR_HEIGHT);
+
+    QTest::newRow("landscape90") << M::Landscape << M::Angle90
+            << QRectF(0, 0, thumbnailStyleWidth, thumbnailStyleHeight)
+            << QRectF(0, 0, Ut_SwitcherButtonView::returnedPixmapWidth - NAVIGATION_BAR_HEIGHT, Ut_SwitcherButtonView::returnedPixmapHeight);
+
+    // FIXME: add tests for portrait and other angles
+}
+
+void Ut_SwitcherButtonView::testDrawBackground()
+{
+    QPainter painter;
+    QFETCH(M::Orientation, orientation);
+    QFETCH(M::OrientationAngle, orientationAngle);
+    QFETCH(QRectF, targetRect);
+    QFETCH(QRectF, sourceRect);
+
+    m_subject->modifiableStyle()->setIconSize(QSize(thumbnailStyleWidth, thumbnailStyleHeight));
+    QPoint thumbnailPosition(0, m_subject->titleLabel->size().height());
+
+    gMSceneManagerStub->stubSetReturnValue("orientation", orientation);
+    gMSceneManagerStub->stubSetReturnValue("orientationAngle", orientationAngle);
+    m_subject->drawBackground(&painter, NULL);
+
+    // Adjust title height for thumbnail position
+    if (orientationAngle == M::Angle0 && orientation == M::Landscape) {
+        targetRect.adjust(0, m_subject->titleLabel->size().height(), 0, m_subject->titleLabel->size().height());
+    } else if (orientationAngle == M::Angle90 && orientation == M::Landscape) {
+        targetRect.adjust(-(m_subject->titleLabel->size().height() + thumbnailStyleWidth), 0, -(m_subject->titleLabel->size().height() + thumbnailStyleWidth), 0);
+    }
+
+    QCOMPARE(drawPixmapRect, targetRect);
+    QCOMPARE(drawPixmapSourceRect, sourceRect);
+
+    // When the background is drawn the icon geometry should be updated if necessary
+    QVERIFY(m_subject->updateXWindowIconGeometryTimer.isActive());
+}
+
+void Ut_SwitcherButtonView::testUpdateXWindowIconGeometryIfNecessary()
+{
+    // When no timer is running and the geometry differs from what has already been set the timer should be started
+    m_subject->updateXWindowIconGeometryIfNecessary();
+    QVERIFY(timerStarted);
+
+    // If a timer has already been started it should not be started again
+    timerStarted = false;
+    m_subject->updateXWindowIconGeometryIfNecessary();
+    QVERIFY(!timerStarted);
+
+    // When the geometry is the same as what has already been set the timer should not be started
+    m_subject->updateXWindowIconGeometry();
+    m_subject->updateXWindowIconGeometryTimer.stop();
+    m_subject->updateXWindowIconGeometryIfNecessary();
+    QVERIFY(!m_subject->updateXWindowIconGeometryTimer.isActive());
+
+    // Test signal connections
+    QVERIFY(disconnect(&m_subject->updateXWindowIconGeometryTimer, SIGNAL(timeout()), m_subject, SLOT(updateXWindowIconGeometry())));
+}
+
+void Ut_SwitcherButtonView::testUpdateXWindowIconGeometry()
+{
+    m_subject->modifiableStyle()->setIconSize(QSize(thumbnailStyleWidth, thumbnailStyleHeight));
+    m_subject->updateXWindowIconGeometry();
+
+    // XChangeProperty should be called for the window of the button and _NET_WM_ICON_GEOMETRY property should be filled with 4 32-bit values which should contain the icon geometry
+    QRectF iconSceneGeometry(QPointF(0, m_subject->titleLabel->size().height()), QSizeF(thumbnailStyleWidth, thumbnailStyleHeight));
+    QCOMPARE(xChangePropertyWindow, button->xWindow());
+    QCOMPARE(xChangePropertyProperty, (Atom)TEST_NET_WM_ICON_GEOMETRY_ATOM);
+    QCOMPARE(xChangePropertyFormat, 32);
+    QCOMPARE(xChangePropertyNElements, 4);
+    unsigned int *iconGeometry = (unsigned int *)xChangePropertyData;
+    QCOMPARE(iconGeometry[0], (unsigned int)iconSceneGeometry.x());
+    QCOMPARE(iconGeometry[1], (unsigned int)iconSceneGeometry.y());
+    QCOMPARE(iconGeometry[2], (unsigned int)iconSceneGeometry.width());
+    QCOMPARE(iconGeometry[3], (unsigned int)iconSceneGeometry.height());
+}
+
 QTEST_APPLESS_MAIN(Ut_SwitcherButtonView)
--- tests/ut_switcherbuttonview/ut_switcherbuttonview.h
+++ tests/ut_switcherbuttonview/ut_switcherbuttonview.h
@@ -51,20 +51,6 @@
 public:
     TestSwitcherButtonView(SwitcherButton &button);
 
-    // helper method to emulate close button click
-    void emulateCloseButtonClick();
-    // helper method to emulate switcher button click
-    void emulateButtonClick();
-    void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *item) const;
-
-    QRectF closeRect() const {
-        return SwitcherButtonView::closeRect();
-    }
-
-    QRectF iconRect() const {
-        return SwitcherButtonView::iconRect();
-    }
-
     SwitcherButtonStyle *modifiableStyle() {
         SwitcherButtonStyleContainer &sc = style();
         const SwitcherButtonStyle *const_s = sc.operator ->();
@@ -99,6 +85,9 @@
     // Switch for making the close timer timeout to occur immediately or not
     static bool timerImmediateTimeout;
 
+    // For checking whether a timer is started even if it has already been started
+    static bool timerStarted;
+
     // For checking that the window pixmaps get freed
     static QList<Pixmap> allocatedPixmaps;
     static Pixmap lastPixmap;
@@ -109,9 +98,25 @@
     // The X error handler to be used
     static XErrorHandler xErrorHandler;
 
+    // For catching XChangeProperty parameters
+    static Display *xChangePropertyDisplay;
+    static Window xChangePropertyWindow;
+    static Atom xChangePropertyProperty;
+    static Atom xChangePropertyType;
+    static int xChangePropertyFormat;
+    static int xChangePropertyMode;
+    static unsigned char xChangePropertyData[16];
+    static int xChangePropertyNElements;
+
     // Whether a Damage object has been created
     static bool damageCreated;
     static unsigned long damageHandle;
+    static Display *damageDisplay;
+
+    // Subtract parameters
+    static bool damageSubtracted;
+    static unsigned long damageSubtractHandle;
+    static Display *damageSubtractDisplay;
 
     // Main window
     static MainWindow *mainWindow;
@@ -128,6 +133,14 @@
     // To see whether update() was called for the view
     static bool viewUpdateCalled;
 
+    // QPainter::DrawPixmap() data
+    static QRectF drawPixmapRect;
+    static QRectF drawPixmapSourceRect;
+
+    // QPixmap data
+    static int returnedPixmapWidth;
+    static int returnedPixmapHeight;
+
 private:
     TestHomeApplication *app;
 
@@ -149,16 +162,23 @@
     void cleanup();
     void initTestCase();
     void cleanupTestCase();
-    void testMousePressRelease();
     void testClosingWithTimeout();
     void testClosingWithoutTimeout();
     void testXWindow();
-    void testXWindowWithXError();
-    void testTextOpacity();
     void testViewModeChange();
+    void testApplyingStyle();
     void testDamageEventForKnownDamage();
     void testDamageEventForUnknownDamage();
     void testEnterExitDisplay();
+    void testXDamageSubtractWhenDisplayEntered();
+    void testCloseButtonTranslate();
+    void testBoundingRect();
+    void testThumbnailPosition();
+    void testSignalConnections();
+    void testDrawBackground_data();
+    void testDrawBackground();
+    void testUpdateXWindowIconGeometryIfNecessary();
+    void testUpdateXWindowIconGeometry();
 };
 
 #endif //_UT_SWITCHERBUTTONVIEW_
--- tests/ut_switcherview/ut_switcherview.cpp
+++ tests/ut_switcherview/ut_switcherview.cpp
@@ -20,6 +20,7 @@
 #include <MApplicationPage>
 #include <MGridLayoutPolicy>
 #include <MLinearLayoutPolicy>
+#include <QGraphicsLayout>
 #include "mwindow_stub.h"
 #include "ut_switcherview.h"
 #include "mainwindow_stub.h"
@@ -29,10 +30,12 @@
 #include "switcher_stub.h"
 #include "switcherbutton.h"
 #include "x11wrapper_stub.h"
+#include "windowinfo_stub.h"
 #include "pagedpanning.h"
+#include "pagedviewport.h"
 
 static void setSwitcherButtonSize(QList< QSharedPointer<SwitcherButton> > &buttonList, const QSizeF &size);
-static void verifyContentMarginValues(qreal top, qreal bottom, qreal target);
+static void verifyEqualContentMarginValues(qreal first, qreal second, qreal target);
 
 SwitcherModel* g_switcherModel;
 QMap<SwitcherButton *, Window> g_windowButtonMap;
@@ -85,9 +88,8 @@
 }
 
 // SwitcherButton stubs
-SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window, WindowInfo::WindowPriority windowPriority) :
-    MButton(title, parent),
-    priority(windowPriority)
+SwitcherButton::SwitcherButton(const QString &title, MWidget *parent, Window window) :
+    MButton(title, parent)
 {
     Q_UNUSED(title);
     Q_UNUSED(parent);
@@ -113,26 +115,16 @@
 {
 }
 
-void SwitcherButton::setGeometry(const QRectF &)
-{
-}
-
-void SwitcherButton::updateIconGeometry()
-{
-}
-
 void SwitcherButton::resetState()
 {
 }
 
-WindowInfo::WindowPriority SwitcherButton::windowPriority() const
+void SwitcherButton::enterDisplayEvent()
 {
-    return priority;
 }
 
-void SwitcherButton::setWindowPriority(WindowInfo::WindowPriority windowPriority)
+void SwitcherButton::exitDisplayEvent()
 {
-    priority = windowPriority;
 }
 
 Window SwitcherButton::xWindow()
@@ -149,7 +141,6 @@
                                               dragThreshold_(0.5),
                                               pageSnapSpringK_(0.7),
                                               pageSnapFriction_(0.7),
-                                              previousPointerPressed(false),
                                               previousPosition(0),
                                               targetPage(0),
                                               pageWidth(0)
@@ -169,6 +160,9 @@
     emit pageChanged(itemIndex);
 }
 
+void PagedPanning::setFirstPagePosition() {
+}
+
 void PagedPanning::panToCurrentPage()
 {
     emit pageChanged(currentPage);
@@ -205,20 +199,21 @@
 {
 }
 
-void Ut_SwitcherView::initTestCase()
+void PagedPanning::pointerPress(const QPointF &pos)
 {
-    static int argc = 1;
-    static char *app_name = (char *)"./ut_switcherview";
-    app = new MApplication(argc, &app_name);
-    mSceneManager = new MSceneManager(NULL, NULL);
-    gMWindowStub->stubSetReturnValue("sceneManager", mSceneManager);
+    Q_UNUSED(pos);
 }
 
-void Ut_SwitcherView::cleanupTestCase()
+void PagedPanning::pointerMove(const QPointF &pos)
+{
+    Q_UNUSED(pos);
+}
+
+void PagedPanning::pointerRelease()
 {
-    delete app;
 }
 
+
 QList< QSharedPointer<SwitcherButton> > Ut_SwitcherView::createButtonList(int buttons)
 {
     QList< QSharedPointer<SwitcherButton> > buttonList;
@@ -236,24 +231,6 @@
     }
 }
 
-void Ut_SwitcherView::init()
-{
-    g_panRequested = false;
-    // Create test switcher
-    switcher = new Switcher();
-    g_switcherModel = new SwitcherModel;
-    switcher->setModel(g_switcherModel);
-    m_subject = new TestSwitcherView(switcher);
-    switcher->setView(m_subject);
-    gSwitcherStub->stubReset();
-}
-
-void Ut_SwitcherView::cleanup()
-{
-    delete m_subject;
-    delete g_switcherModel;
-}
-
 void Ut_SwitcherView::verifyButtonModesInOverviewMode(QList< QSharedPointer<SwitcherButton> > &buttonList)
 {
     int buttons = buttonList.count();
@@ -264,28 +241,6 @@
             QCOMPARE(buttonList[i].data()->model()->viewMode(), SwitcherButtonModel::Medium);
         }
     }
-    /*
-    int buttons = buttonList.count();
-    if (gMSceneManagerStub->orientation() == M::Landscape){
-        for(int i = 0; i < buttons; i++){
-            if (buttons < 3) {
-                QVERIFY(buttonList[i].data()->model()->viewMode() == SwitcherButtonModel::Large);
-            } else {
-                QVERIFY(buttonList[i].data()->model()->viewMode() == SwitcherButtonModel::Medium);
-            }
-        }
-    } else {
-        for(int i = 0; i < buttons; i++){
-            if (buttons < 3) {
-                QVERIFY(buttonList[i].data()->model()->viewMode() == SwitcherButtonModel::Large);
-            } else if (buttons < 5) {
-                QVERIFY(buttonList[i].data()->model()->viewMode() == SwitcherButtonModel::Medium);
-            } else {
-                QVERIFY(buttonList[i].data()->model()->viewMode() == SwitcherButtonModel::Small);
-            }
-        }
-    }
-    */
 }
 
 void Ut_SwitcherView::verifyButtonModesInOverviewMode(M::Orientation orientation)
@@ -321,29 +276,38 @@
     if (g_switcherModel->buttons().size() == 0) {
         // Test the overview policy margins
         m_subject->overviewPolicy->getContentsMargins(&left, &top, &right, &bottom);
-        verifyContentMarginValues(top, bottom, 0.0);
+        verifyEqualContentMarginValues(top, bottom, 0.0);
+        verifyEqualContentMarginValues(left, right, 0.0);
+
         // Test the detail view policy margins
         m_subject->detailPolicy->getContentsMargins(&left, &top, &right, &bottom);
-        verifyContentMarginValues(top, bottom, 0.0);
-    } else if (g_switcherModel->buttons().size() < 3) {
-        // Test the overview policy margins
-        m_subject->overviewPolicy->getContentsMargins(&left, &top, &right, &bottom);
-        qreal numberOfRowSpacings = qMax(0, m_subject->overviewPolicy->rowCount() - 1);
-        qreal heightTakenByRowSpacings =  numberOfRowSpacings * m_subject->modifiableStyle()->buttonVerticalSpacing();
-        qreal verticalMargin = (m_subject->geometry().height() - (buttonSize.height() * m_subject->overviewPolicy->rowCount() + heightTakenByRowSpacings)) / 2;
+        verifyEqualContentMarginValues(top, bottom, 0.0);
+        verifyEqualContentMarginValues(left, right, 0.0);
+    } else {
+        qreal horizontalMargin, verticalMargin;
+        if (g_switcherModel->buttons().size() < 3) {
+            // Test the overview policy vertical margins
+            m_subject->overviewPolicy->getContentsMargins(&left, &top, &right, &bottom);
+            qreal numberOfRowSpacings = qMax(0, m_subject->overviewPolicy->rowCount() - 1);
+            qreal heightTakenByRowSpacings =  numberOfRowSpacings * m_subject->modifiableStyle()->buttonVerticalSpacing();
+            verticalMargin = (m_subject->geometry().height() - (buttonSize.height() * m_subject->overviewPolicy->rowCount() + heightTakenByRowSpacings)) / 2;
 
-        verifyContentMarginValues(top, bottom, verticalMargin);
+            verifyEqualContentMarginValues(top, bottom, verticalMargin);
+        } else {
+            // Overview policy vertical margins are determined by the style
+            // TODO this should be tested.
+        }
 
-        // Test the detail view policy margins
+        // TODO test the overview policy horizontal margins!
+        // TODO test the overview policy spacings!
+
+        // Test the detail view policy margins and horizontal spacing
         m_subject->detailPolicy->getContentsMargins(&left, &top, &right, &bottom);
+        horizontalMargin = (m_subject->geometry().width() - buttonSize.width()) / 2;
         verticalMargin = (m_subject->geometry().height() - buttonSize.height()) / 2;
-        verifyContentMarginValues(top, bottom, verticalMargin);
-    } else {
-        // Overview policy margins are determined by the style,
-        // just test the detail view policy margins
-        m_subject->detailPolicy->getContentsMargins(&left, &top, &right, &bottom);
-        qreal verticalMargin = (m_subject->geometry().height() - buttonSize.height()) / 2;
-        verifyContentMarginValues(top, bottom, verticalMargin);
+        verifyEqualContentMarginValues(top, bottom, verticalMargin);
+        verifyEqualContentMarginValues(left, right, horizontalMargin);
+        QCOMPARE(m_subject->detailPolicy->horizontalSpacing(), horizontalMargin / 2);
     }
 }
 
@@ -354,32 +318,46 @@
     }
 }
 
-void verifyContentMarginValues(qreal top, qreal bottom, qreal target)
+void verifyEqualContentMarginValues(qreal first, qreal second, qreal target)
 {
-    QCOMPARE(top, bottom);
-    QCOMPARE(top, target);
+    QCOMPARE(first, second);
+    QCOMPARE(first, target);
 }
 
 /*
  * Switcher detail view tests
  */
 
-void Ut_SwitcherView::testAutoPanningInDetailView()
+void Ut_SwitcherView::initTestCase()
 {
-    g_switcherModel->setSwitcherMode(SwitcherModel::Detailview);
-
-    QCOMPARE(g_panRequested, false);
+    static int argc = 1;
+    static char *app_name = (char *)"./ut_switcherview";
+    app = new MApplication(argc, &app_name);
+    mSceneManager = new MSceneManager(NULL, NULL);
+    gMWindowStub->stubSetReturnValue("sceneManager", mSceneManager);
+}
 
-    QList< QSharedPointer<SwitcherButton> > buttonList = createButtonList(4);
+void Ut_SwitcherView::cleanupTestCase()
+{
+    delete app;
+}
 
-    // Change the first button's priority to
-    // trigger the panning of the view to show it
-    buttonList.first().data()->setWindowPriority(WindowInfo::Call);
-    // Update the model with the modified list
-    g_switcherModel->setButtons(buttonList);
+void Ut_SwitcherView::init()
+{
+    g_panRequested = false;
+    // Create test switcher
+    switcher = new Switcher();
+    g_switcherModel = new SwitcherModel;
+    switcher->setModel(g_switcherModel);
+    m_subject = new TestSwitcherView(switcher);
+    switcher->setView(m_subject);
+    gSwitcherStub->stubReset();
+}
 
-    // SwitcherView should have called the physics integrator's pan method
-    QCOMPARE(g_panRequested, true);
+void Ut_SwitcherView::cleanup()
+{
+    delete m_subject;
+    delete g_switcherModel;
 }
 
 void Ut_SwitcherView::testSnapIndexChangedInDetailView()
@@ -440,23 +418,6 @@
  * Switcher overview tests
  */
 
-void Ut_SwitcherView::testAutoPanningInOverView()
-{
-    QCOMPARE(g_panRequested, false);
-
-    QList< QSharedPointer<SwitcherButton> > buttonList = createButtonList(6);
-    g_switcherModel->setSwitcherMode(SwitcherModel::Overview);
-
-    // Change the first button's priority to
-    // trigger the panning of the view to show it
-    buttonList.first().data()->setWindowPriority(WindowInfo::Call);
-    // Update the model with the modified list
-    g_switcherModel->setButtons(buttonList);
-
-    // SwitcherView should have called the physics integrator's pan method
-    QCOMPARE(g_panRequested, true);
-}
-
 void Ut_SwitcherView::testButtonModesInOverviewMode()
 {
     m_subject->modifiableStyle()->setRowsPerPage(2);
@@ -504,7 +465,7 @@
     QCOMPARE(m_subject->focusedSwitcherButton, 0);
 }
 
-void Ut_SwitcherView::testSwitcherButtonVerticalAlignment()
+void Ut_SwitcherView::testSwitcherButtonAlignment()
 {
     g_switcherModel->setSwitcherMode(SwitcherModel::Overview);
     gMSceneManagerStub->stubSetReturnValue("orientation", M::Landscape);
@@ -545,9 +506,6 @@
     // Change the orientation to portrait
     gMSceneManagerStub->stubSetReturnValue("orientation", M::Portrait);
 
-    // Called by the SceneManager when orientation is about to change
-    m_subject->hideButtons();
-
     switcherHeight = 600.0;
     switcherWidth = 400.0;
     m_subject->setGeometry(QRectF(0, 0, switcherWidth, switcherHeight));
@@ -565,5 +523,20 @@
     verifyLayoutPolicyContentMargins(notSizeAtAll);
 }
 
+void Ut_SwitcherView::testRemovingButtons()
+{
+    QList< QSharedPointer<SwitcherButton> > list(createButtonList(2));
+    QSharedPointer<SwitcherButton> removedButton = list.at(0);
+    g_switcherModel->setButtons(list);
+    QGraphicsLayout *layout = dynamic_cast<PagedViewport *>(switcher->layout()->itemAt(0))->widget()->layout();
+    QCOMPARE(layout->count(), 2);
+
+    list.removeAt(0);
+    g_switcherModel->setButtons(list);
+
+    QCOMPARE(layout->count(), 1);
+    // verify that removed button was not deleted while there is still ref in QSharedPointer
+    QVERIFY(!removedButton.isNull());
+}
 
 QTEST_APPLESS_MAIN(Ut_SwitcherView)
--- tests/ut_switcherview/ut_switcherview.h
+++ tests/ut_switcherview/ut_switcherview.h
@@ -45,17 +45,18 @@
     void cleanup();
 
     // Test cases for detail view
-    void testAutoPanningInDetailView();
     void testSnapIndexChangedInDetailView();
     void testPanningStoppedInDetailView();
 
     // Test cases for over view
-    void testAutoPanningInOverView();
     void testButtonModesInOverviewMode();
     void testPanningStoppedInOverView();
 
     // Test that the buttons are positioned correctly
-    void testSwitcherButtonVerticalAlignment();
+    void testSwitcherButtonAlignment();
+
+    // Test that buttons are removed correctly
+    void testRemovingButtons();
 
 private:
     void verifyButtonModesInOverviewMode(M::Orientation orientation);
--- tests/ut_switcherview/ut_switcherview.pro
+++ tests/ut_switcherview/ut_switcherview.pro
@@ -39,6 +39,5 @@
 
 # service classes
 SOURCES += ../stubs/stubbase.cpp \
-    $$SRCDIR/windowinfo.cpp
 
 include(../common_bot.pri)
--- tests/ut_windowinfo/ut_windowinfo.cpp
+++ tests/ut_windowinfo/ut_windowinfo.cpp
@@ -17,16 +17,144 @@
 **
 ****************************************************************************/
 
+#include <string.h>
 #include "ut_windowinfo.h"
 #include "windowinfo.h"
+#include "x11wrapper.h"
 
+#define ATOM_TYPE 1
+#define ATOM_TYPE_NORMAL 2
+#define ATOM_TYPE_DESKTOP 3
+#define ATOM_TYPE_TEXT_PROPERTY 4
+#define ATOM_STATE 5
+
+Atom X11Wrapper::XInternAtom(Display *, const char* atom_name, Bool)
+{
+    if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE") == 0) {
+        return ATOM_TYPE;
+    } else if (strcmp(atom_name, "_NET_WM_NAME") == 0) {
+        return ATOM_TYPE_TEXT_PROPERTY;
+    } else if (strcmp(atom_name, "_NET_WM_STATE") == 0) {
+        return ATOM_STATE;
+    }
+    return 0;
+}
+
+int X11Wrapper::XSelectInput(Display *, Window , long)
+{
+    return 0;
+}
+
+Status X11Wrapper::XGetWindowAttributes(Display *, Window, XWindowAttributes *)
+{
+    return 0;
+}
+
+int X11Wrapper::XGetWindowProperty(Display *, Window , Atom property, long , long , Bool , Atom , Atom *, int *, unsigned long *nitems_return, unsigned long *, unsigned char **prop_return)
+{
+    if (property == ATOM_TYPE) {
+        *nitems_return = 2;
+        *prop_return = new unsigned char[2 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_TYPE_NORMAL;
+        atom[1] = ATOM_TYPE_DESKTOP;
+        return Success;
+    } else if (property == ATOM_STATE) {
+        *nitems_return = 1;
+        *prop_return = new unsigned char[1 * sizeof(Atom)];
+        Atom* atom = (Atom *) * prop_return;
+        atom[0] = ATOM_STATE;
+        return Success;
+    }
+    return BadAtom;
+}
+
+int X11Wrapper::XFree(void *data)
+{
+    if (data != NULL) {
+        delete [](unsigned char *)data;
+    }
+    return 0;
+}
+
+bool textValueFromGetTextProperty = true;
+Status X11Wrapper::XGetWMName(Display *, Window, XTextProperty *textProperty)
+{
+    if (textValueFromGetTextProperty) {
+        return 0;
+    }
+    QString textValue("WindowTitleXGetWMName");
+    std::string::size_type strSize = textValue.toStdString().length();
+    textProperty->value = new unsigned char[strSize + 1];
+    strncpy((char *)textProperty->value, textValue.toStdString().c_str(), strSize + 1);
+    return 1;
+}
+
+Status X11Wrapper::XGetTextProperty(Display *, Window , XTextProperty *text_prop_return, Atom atom)
+{
+    if (!textValueFromGetTextProperty || atom != ATOM_TYPE_TEXT_PROPERTY) {
+        return 0;
+    }
+    QString textValue("WindowTitleFromXGetTextProperty");
+    std::string::size_type strSize = textValue.toStdString().length();
+    text_prop_return->value = new unsigned char[strSize + 1];
+    strncpy((char *)text_prop_return->value, textValue.toStdString().c_str(), strSize + 1);
+    return 1;
+}
+
+XWMHints *X11Wrapper::XGetWMHints(Display *, Window)
+{
+    return 0;
+}
+
+int X11Wrapper::XFreePixmap(Display *, Pixmap)
+{
+    return 0;
+}
+
+Pixmap X11Wrapper::XCompositeNameWindowPixmap(Display *, Window)
+{
+    return 0;
+}
+
+Damage X11Wrapper::XDamageCreate(Display *, Drawable, int)
+{
+    return 0;
+}
+
+void X11Wrapper::XDamageDestroy(Display *, Damage)
+{
+
+}
+
+int X11Wrapper::XSync(Display *, Bool)
+{
+    return 0;
+}
+
+XErrorHandler X11Wrapper::XSetErrorHandler(XErrorHandler)
+{
+    return 0;
+}
+
+int X11Wrapper::XChangeProperty(Display *, Window, Atom, Atom, int, int, unsigned char *, int)
+{
+    return 0;
+}
+
+Status X11Wrapper::XSendEvent(Display *, Window, Bool, long, XEvent *)
+{
+    return 0;
+}
 
 void Ut_WindowInfo::initTestCase()
 {
+    windowInfo = new WindowInfo(1);
 }
 
 void Ut_WindowInfo::cleanupTestCase()
 {
+    delete windowInfo;
 }
 
 void Ut_WindowInfo::init()
@@ -39,28 +167,19 @@
 
 void Ut_WindowInfo::testGetters()
 {
-    // Title of the window
-    QString title = "Title";
-    // Window ID
-    Window window = 1;
-    // Window attributes
-    XWindowAttributes attributes;
-    memset(&attributes, 0, sizeof(XWindowAttributes));
-    attributes.depth = 16;
-    attributes.width = 320;
-    attributes.height = 256;
-    // Window pixmap ID
-    Pixmap pixmap = 3;
-
-    WindowInfo *info = new WindowInfo(title, window, attributes, pixmap);
-    QCOMPARE(info->title(), title);
-    QCOMPARE(info->window(), window);
-    QCOMPARE(info->windowAttributes().depth, 16);
-    QCOMPARE(info->windowAttributes().width, 320);
-    QCOMPARE(info->windowAttributes().height, 256);
-    QCOMPARE(info->icon(), pixmap);
+    textValueFromGetTextProperty = true;
+    bool updated = windowInfo->updateWindowTitle();
+    QVERIFY(updated);
+    QCOMPARE(windowInfo->title(), QString("WindowTitleFromXGetTextProperty"));
+    updated = false;
+    textValueFromGetTextProperty = false;
+    updated = windowInfo->updateWindowTitle();
+    QVERIFY(updated);
+    QCOMPARE(windowInfo->title(), QString("WindowTitleXGetWMName"));
+
+    QCOMPARE(windowInfo->types().count(), 2);
 
-    delete info;
+    QCOMPARE(windowInfo->states().count(), 1);
 }
 
 QTEST_MAIN(Ut_WindowInfo)
--- tests/ut_windowinfo/ut_windowinfo.h
+++ tests/ut_windowinfo/ut_windowinfo.h
@@ -23,6 +23,8 @@
 #include <QtTest/QtTest>
 #include <QObject>
 
+class WindowInfo;
+
 class Ut_WindowInfo : public QObject
 {
     Q_OBJECT
@@ -38,6 +40,9 @@
     void cleanup();
     // Test getters
     void testGetters();
+
+private:
+    WindowInfo* windowInfo;
 };
 
 #endif
--- tests/ut_windowinfo/ut_windowinfo.pro
+++ tests/ut_windowinfo/ut_windowinfo.pro
@@ -6,10 +6,6 @@
     ut_windowinfo.cpp \
     $$SRCDIR/windowinfo.cpp
 
-# base classes
-SOURCES += \
-
-
 # unit test and unit
 HEADERS += \
     ut_windowinfo.h \
--- tests/ut_x11helper
+++ tests/ut_x11helper
-(directory)
--- tests/ut_x11helper/ut_x11helper.cpp
+++ tests/ut_x11helper/ut_x11helper.cpp
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "ut_x11helper.h"
-#include "x11helper.h"
-#include "x11wrapper.h"
-
-static const Atom NET_WM_STATE_ATOM = 1;
-
-// static variables in the test class
-bool Ut_X11Helper::propertyQuerySucceeds = true;
-bool Ut_X11Helper::propertySizeQuerySucceeds = true;
-
-// X11Wrapper stubs
-Atom X11Wrapper::XInternAtom(Display *display, const char *atom_name, Bool only_if_exists)
-{
-    Atom returnValue = 0;
-
-    if (display == (Display *)1 && only_if_exists == False) {
-        if (QString(atom_name) == "_NET_WM_STATE") {
-            returnValue = NET_WM_STATE_ATOM;
-        }
-    }
-
-    return returnValue;
-}
-
-// This is the list of atoms that gets reported to the window
-const QVector<Atom> gNetWmStateAtoms(QVector<Atom>() << 1 << 2);
-const int gNetWmStateAtomsCount = gNetWmStateAtoms.count();
-
-int X11Wrapper::XGetWindowProperty(Display *display, Window w, Atom property, long long_offset, long long_length, Bool del, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return)
-{
-    int returnValue = Success;
-
-    // Let's set some common attributes. These are modified later if needed
-    *actual_type_return = XA_ATOM;
-    *actual_format_return = 32;
-
-    if (display != (Display *)1 || w != 1 || property != NET_WM_STATE_ATOM || del != False || req_type != XA_ATOM) {
-        returnValue = BadAtom;
-    } else {
-        if (long_offset == 0 && long_length == 0) {
-            // Since long_length == 0, the requester wants to know the number of items available
-            *bytes_after_return = sizeof(Atom) * gNetWmStateAtomsCount;
-            // These rest don't really matter in this request, but let's set them anyway
-            *nitems_return = 0;
-            *prop_return = new unsigned char[0];
-
-            if (!Ut_X11Helper::propertySizeQuerySucceeds) {
-                returnValue = BadAtom;
-            }
-        } else if (long_offset == 0 && long_length == gNetWmStateAtomsCount) {
-            // Since long_length == gNetWmStateAtomsCount, the requester wants to know the actual data. Let's return it
-            *nitems_return = gNetWmStateAtomsCount;
-            *prop_return = new unsigned char[gNetWmStateAtomsCount * sizeof(Atom)];
-            Atom *atom = (Atom *) * prop_return;
-            for (int i = 0; i < gNetWmStateAtomsCount; ++i) {
-                atom[i] = gNetWmStateAtoms.at(i);
-            }
-            // These rest don't really matter in this request, but let's set them anyway
-            *bytes_after_return = sizeof(Atom) * gNetWmStateAtomsCount;
-
-            if (!Ut_X11Helper::propertyQuerySucceeds) {
-                returnValue = BadAtom;
-            }
-        }
-    }
-
-    return returnValue;
-}
-
-int X11Wrapper::XFree(void *data)
-{
-    if (data != NULL) {
-        delete[](unsigned char *)data;
-    }
-    return 0;
-}
-
-void Ut_X11Helper::initTestCase()
-{
-}
-
-void Ut_X11Helper::cleanupTestCase()
-{
-}
-
-void Ut_X11Helper::init()
-{
-    propertyQuerySucceeds = true;
-    propertySizeQuerySucceeds = true;
-}
-
-void Ut_X11Helper::cleanup()
-{
-}
-
-void Ut_X11Helper::testGetNetWmState()
-{
-    QVector<Atom> atoms = X11Helper::getNetWmState((Display *)1, 1);
-    QCOMPARE(atoms, gNetWmStateAtoms);
-}
-
-void Ut_X11Helper::testGetNetWmStatePropertyQueryFails()
-{
-    propertyQuerySucceeds = false;
-    QVector<Atom> atoms = X11Helper::getNetWmState((Display *)1, 1);
-    QCOMPARE(atoms.count(), 0);
-}
-
-void Ut_X11Helper::testGetNetWmStateProperySizeQueryFails()
-{
-    propertySizeQuerySucceeds = false;
-    QVector<Atom> atoms = X11Helper::getNetWmState((Display *)1, 1);
-    QCOMPARE(atoms.count(), 0);
-}
-
-QTEST_APPLESS_MAIN(Ut_X11Helper)
--- tests/ut_x11helper/ut_x11helper.h
+++ tests/ut_x11helper/ut_x11helper.h
-/***************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (directui at nokia.com)
-**
-** This file is part of mhome.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at directui at nokia.com.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation
-** and appearing in the file LICENSE.LGPL included in the packaging
-** of this file.
-**
-****************************************************************************/
-
-#ifndef UT_X11HELPER_H
-#define UT_X11HELPER_H
-
-#include <QObject>
-
-class Ut_X11Helper : public QObject
-{
-    Q_OBJECT
-
-public:
-    static bool propertyQuerySucceeds;
-    static bool propertySizeQuerySucceeds;
-
-private slots:
-    // Called before the first testfunction is executed
-    void initTestCase();
-    // Called after the last testfunction was executed
-    void cleanupTestCase();
-    // Called before each testfunction is executed
-    void init();
-    // Called after every testfunction
-    void cleanup();
-
-    // Test cases
-    void testGetNetWmState();
-    void testGetNetWmStatePropertyQueryFails();
-    void testGetNetWmStateProperySizeQueryFails();
-
-
-};
-
-#endif
--- tests/ut_x11helper/ut_x11helper.pro
+++ tests/ut_x11helper/ut_x11helper.pro
-include(../common_top.pri)
-TARGET = ut_x11helper
-
-# unit test and unit
-SOURCES += \
-    ut_x11helper.cpp \
-    $$SRCDIR/x11helper.cpp
-
-# unit test and unit
-HEADERS += \
-    ut_x11helper.h \
-    $$SRCDIR/x11helper.h
-
-include(../common_bot.pri)
--- themes/duihome.conf
+++ themes/duihome.conf
@@ -17,7 +17,7 @@
 default = AppletSpaceView
 
 [LauncherButton]
-default = MButtonIconView
+default = LauncherButtonView
 
 [Launcher]
 default = LauncherView
--- themes/style/default.css
+++ themes/style/default.css
@@ -38,19 +38,19 @@
     horizontal-align: left;
 }
 
-MSceneWindowStyle#LauncherWindow {
+MSceneWindowStyle#SwitcherWindow {
     margin-left: 0;
     margin-right: 0;
     margin-top: 0;
     margin-bottom: 0;
     padding-left: 0;
     padding-right: 0;
-    padding-top: 0;
-    padding-bottom: 0;
-    background-opacity: 0.5;
+    /* Add top padding so that the launcher does not go under the status area */
+    padding-top: 2.8mm;
+    padding-bottom: 8.8mm; /* 76 + 12 == quick launch bar + ?;*/
 }
 
-MSceneWindowStyle#AppletSpaceWindow {
+MSceneWindowStyle#LauncherWindow {
     margin-left: 0;
     margin-right: 0;
     margin-top: 0;
@@ -59,39 +59,6 @@
     padding-right: 0;
     padding-top: 0;
     padding-bottom: 0;
-    minimum-size: 100% -1;
-    preferred-size: 100% -1;
-    maximum-size: 100% -1;
-}
-
-AppletSpaceStyle {
-    extend-direction: "bottom";
-    background-image: "duibutton-background-pressed" 10px 10px 10px 10px;
-    margin-left: 0;
-    margin-right: 0;
-    margin-top: 0;
-    margin-bottom: 0;
-    padding-left: 1.6mm;
-    padding-right: 1.6mm;
-    padding-top: 1.6mm;
-    padding-bottom: 1.6mm;
-    minimum-size: 100% 100%;
-    preferred-size: 100% -1;
-    maximum-size: 100% -1;
-}
-
-MButtonStyle#AppletSpaceCloseButton {
-    icon-size: $SIZE_ICON_DEFAULT $SIZE_ICON_DEFAULT;
-    preferred-size: 6.4mm 6.4mm;
-    minimum-size: 6.4mm 6.4mm;
-    maximum-size: 6.4mm 6.4mm;
-}
-
-MOverlayStyle#AppletSpaceCloseButtonOverlay {
-    minimum-size: 6.4mm 6.4mm;
-    preferred-size: 6.4mm 6.4mm;
-    maximum-size: 6.4mm 6.4mm;
-    offset: 0 0;
 }
 
 MButtonIconStyle {
@@ -143,7 +110,6 @@
 }
 
 LauncherStyle {
-    background-image: "main-menu-background" 0 0 0 15;
     margin-left: 0;
     margin-right: 0;
     margin-top: 0;
@@ -153,7 +119,6 @@
     /* Add top padding so that the launcher does not go under the status area */
     padding-top: 2.8mm;
     padding-bottom: 8.8mm; /* 76 + 12 == quick launch bar + ?;*/
-    background-opacity: 0;
 }
 
 LauncherPageStyle {
@@ -223,7 +188,7 @@
     offset: 0 0;
 }
 
-MButtonIconStyle#LauncherButton {
+LauncherButtonStyle {
     font: $FONT_XSMALL;
     text-color: #ffffff;
 
@@ -241,13 +206,26 @@
     text-margin-right: 0;
     text-margin-bottom: 0;
 
-    preferred-size: 14.0mm 10.6mm;
+    minimum-size: 11.75mm 10.6mm;
+    preferred-size: 11.75mm 10.6mm;
+    maximum-size: 11.75mm 10.6mm;
 
     /* The size of the icon if the button represents a shortcut */
     icon-size: 8mm 8mm;
 
     press-feedback: press;
     release-feedback: release;
+
+    /* The timeout for the progress indicator (in milliseconds) */
+    progress-indicator-timeout: 10000;
+    /* The number of milliseconds in which the given progress indicator images are animated */
+    progress-indicator-animation-duration: 8000;
+    /* The list of IDs of the images to be shown in the progress indicator separated by spaces */
+    progress-indicator-image-list: "meegotouch-launcher-spinner-large-1 meegotouch-launcher-spinner-large-2 meegotouch-launcher-spinner-large-3 meegotouch-launcher-spinner-large-4 meegotouch-launcher-spinner-large-5 meegotouch-launcher-spinner-large-6 meegotouch-launcher-spinner-large-7 meegotouch-launcher-spinner-large-8 meegotouch-launcher-spinner-large-9 meegotouch-launcher-spinner-large-10 meegotouch-launcher-spinner-large-11 meegotouch-launcher-spinner-large-12 meegotouch-launcher-spinner-large-13 meegotouch-launcher-spinner-large-14 meegotouch-launcher-spinner-large-15 meegotouch-launcher-spinner-large-16";
+}
+
+LauncherButton > MSpinnerStyle {
+    speed: 2;
 }
 
 QuickLaunchBarStyle {
@@ -263,17 +241,21 @@
 
 MButtonIconStyle#QuickLaunchBarButton {
     font: $FONT_SMALL;
-    text-color: #ffffff;
-    margin-left: 0.6mm;
-    margin-right: 0.6mm;
-    margin-top: 0.6mm;
-    margin-bottom: 0.6mm;
+    text-color: $COLOR_INVERTED_FOREGROUND;
+
+    margin-left: $MARGIN_DOUBLE;
+    margin-right: $MARGIN_DOUBLE;
+    margin-top: $MARGIN_DOUBLE;
+    margin-bottom: $MARGIN_DOUBLE;
+
     preferred-size: 6.4mm 12.6mm;
     minimum-size: 6.4mm 12.6mm;
     maximum-size: 6.4mm 12.6mm;
 
     press-feedback: press;
     release-feedback: release;
+
+    icon-size: $SIZE_ICON_LARGE $SIZE_ICON_LARGE;
 }
 
 SwitcherStyle {
@@ -289,17 +271,10 @@
     padding-top: 0;
     padding-bottom: 0;
 
-    /* how much to down scale the non emphasizzed items */
-    scale-factor: 0.8;
-    /* The amount the focused item will "fast-forward" during the transition */
-    fast-forward: 4.0mm;
-    /* The angle that the item will rotate during the transition */
-    item-rotation: 15;
-    /* The amoun the items will overlap when stationary */
-    item-over-lap: 3mm;
-
     button-horizontal-spacing: 0;
     button-vertical-spacing: 0;
+    rows-per-page: 1;
+    columns-per-page: 1;
 }
 
 
@@ -325,21 +300,30 @@
 MAbstractLayoutPolicyStyle#OverviewPolicy {
     margin-top: 6.4mm;
     margin-bottom: 3mm;
+    vertical-spacing: 0.0;
+    horizontal-spacing: 0.0;
+}
+
+MAbstractLayoutPolicyStyle#DetailviewPolicy {
+    margin-top: 6.4mm;
+    margin-bottom: 3mm;
+    vertical-spacing: 0.0;
+    horizontal-spacing: 0.0;
 }
 
 PagedViewportStyle {
     pan-threshold: 15.0;
-    pan-click-threshold: 0.2;
+    pan-click-threshold: 0.1;
     pointer-spring-k: 0.6;
     friction-c: 0.9;
-    sliding-friction-c: 0.08;
+    sliding-friction-c: 1.2;
     border-spring-k: 0.9;
     border-friction-c: 0.9;
 
-    page-snap-spring-k: 0.3;
+    page-snap-spring-k: 0.15;
     page-snap-friction-c: 0.7;
     velocity-threshold: 7.0;
-    drag-threshold: 0.2;
+    drag-threshold: 0.3;
     slide-limit: 0;
 }
 
@@ -352,20 +336,17 @@
     padding-top: 0;
     padding-bottom: 0;
 
-    font: $FONT_DEFAULT;
-    text-color: #FFFFFF;
+    press-feedback:;
+    release-feedback:;
 
-    /* The opacity of the title */
-    text-opacity: 0;
-    /* The position of the icon relative to the top-left corner of the button */
-    icon-position: 0 0;
     /* The image to be drawn as the container for the button */
     container-image:;
 
     /* The close button icon */
     close-icon: ;
 
-    close-button-vertical-position: 0.0;
+    close-button-h-offset: 1.3mm;
+    close-button-v-offset: 1.3mm;
 }
 
 
@@ -377,14 +358,10 @@
 
     icon-size: 1.8mm 1.8mm;
 
-    /* icon aligned to right (48-18=30) */
-    /* icon-align: right; doesn't do the trick.. */
-    padding-left: 3.0mm;
-
     margin-top: 0;
     margin-bottom: 0;
     margin-left: 0;
-    margin-right: 0.3mm;
+    margin-right: 0;
 }
 
 MButtonIconStyle#CloseButtonDetailview
@@ -395,20 +372,14 @@
 
     icon-size: $SIZE_ICON_DEFAULT $SIZE_ICON_DEFAULT;
 
-    /* icon aligned to right (48-32=16) */
-    /* icon-align: right; doesn't do the trick.. */
-    padding-left: 1.6mm;
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 0;
+    margin-right: 0;
 }
 
 /* The default values for the switcher button in the overview mode */
 SwitcherButtonStyle#OverviewButton {
-    /* The amount of space around the label */
-    text-margin-bottom: 0.2mm;
-    text-margin-left: 0.1mm;
-    text-margin-right: 0.1mm;
-
-    text-opacity: 1.0;
-
     margin-bottom: 0;
     margin-left: 0;
     margin-right: 0;
@@ -419,77 +390,55 @@
     padding-right: 0;
     padding-top: 0;
 
-    /* -48/2 - (18 / 2) - 2 */
-    close-button-vertical-position: -3.5mm;
     close-icon: "icon-s-framework-close-thumbnail";
 }
 
 SwitcherButtonStyle#OverviewButton.Portrait:medium {
-    font: $FONT_XSMALL;
-
     preferred-size: 17.4mm 31.3mm;
     minimum-size: 17.4mm 31.3mm;
     maximum-size: 17.4mm 31.3mm;
-    icon-position: 0 3.2mm;
     icon-size: 17.4mm 28.0mm;
 
-    text-margin-top: 0.7mm;
-    text-margin-bottom: 0.7mm;
-    close-button-vertical-position: -4.0mm;
+    close-button-v-offset: 1.3mm;
+    close-button-h-offset: 1.3mm;
 }
 
 SwitcherButtonStyle#OverviewButton.Portrait:large {
-    font: $FONT_XSMALL;
-
     preferred-size: 21mm 37.8mm;
     minimum-size: 21mm 37.8mm;
     maximum-size: 21mm 37.8mm;
-    icon-position: 0 3.2mm;
     icon-size: 21mm 33.4mm;
 
-    text-margin-top: 0.7mm;
-    text-margin-bottom: 0.7mm;
-    close-button-vertical-position: -4.0mm;
+    close-button-v-offset: 1.3mm;
+    close-button-h-offset: 1.3mm;
 }
 
 SwitcherButtonStyle#OverviewButton.Landscape:medium {
-    font: $FONT_XSMALL;
-
     preferred-size: 21.8mm 12.1mm;
     minimum-size: 21.8mm 12.1mm;
     maximum-size: 21.8mm 12.1mm;
-    icon-position: 0 2.3mm;
     icon-size: 21.8mm 9.8mm;
 
-    text-margin-top: 0.25mm;
-    text-margin-bottom: 0.25mm;
-    close-button-vertical-position: -3.5mm;
+    close-button-v-offset: 1.3mm;
+    close-button-h-offset: 1.3mm;
 }
 
 SwitcherButtonStyle#OverviewButton.Landscape:large {
-    font: $FONT_XSMALL;
-
     preferred-size: 37.8mm 21mm;
     minimum-size: 37.8mm 21mm;
     maximum-size: 37.8mm 21mm;
-    icon-position: 0 2.3mm;
     icon-size: 37.8mm 16.6mm;
 
-    text-margin-top: 0.25mm;
-    text-margin-bottom: 0.25mm;
-    close-button-vertical-position: -3.5mm;
+    close-button-v-offset: 1.3mm;
+    close-button-h-offset: 1.3mm;
 }
 
 /*
   Switcher buttons in the detail viewmode
 */
 SwitcherButtonStyle#DetailviewButton {
-    /* The amount of space around the label */
-    text-margin-bottom: 0.5mm;
-    text-margin-left: 0.6mm;
-    text-margin-right: 0.6mm;
-
-    close-button-vertical-position: -3.6mm;
+    close-button-v-offset: 1.3mm;
+    close-button-h-offset: 1.3mm;
 }
 
 SwitcherButtonStyle#DetailviewButton.Portrait {
@@ -501,7 +450,6 @@
 }
 
 SwitcherButtonStyle#DetailviewButton.Portrait:large {
-    text-opacity: 1.0;
     close-icon: "icon-m-framework-close-thumbnail";
 }
 
@@ -514,9 +462,38 @@
 }
 
 SwitcherButtonStyle#DetailviewButton.Landscape:large {
-    text-opacity: 1.0;
     close-icon: "icon-m-framework-close-thumbnail";
 }
+
+MLabelStyle#SwitcherButtonTitleLabelDetailview {
+    font: $FONT_DEFAULT;
+    color: #FFFFFF;
+
+    preferred-size: -1 3mm;
+    minimum-size: -1 3mm;
+    maximum-size: -1 3mm;
+
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 0.6mm;
+    margin-right: 0.6mm;
+}
+
+MLabelStyle#SwitcherButtonTitleLabelOverview {
+    font: $FONT_XSMALL;
+    color: #FFFFFF;
+
+    preferred-size: -1 2.3mm;
+    minimum-size: -1 2.3mm;
+    maximum-size: -1 2.3mm;
+
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 0.1mm;
+    /* adjust to overlap the close button horizontal offset */
+    margin-right: -1.3mm;
+}
+
 /* switcher button detail view end */
 
 @import "mashupcanvas.css";
--- themes/svg/icon-s-current-page.svg
+++ themes/svg/icon-s-current-page.svg
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="icon-s-current-page-layer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
-	 x="0px" y="0px" width="10px" height="10px" viewBox="0 0 10 10" enable-background="new 0 0 10 10" xml:space="preserve">
-<g id="icon-s-current-page">
-	<rect fill="none" width="10" height="10"/>
-	<g>
-		<circle fill="#333333" cx="5" cy="5" r="5"/>
-	</g>
-	<g>
-		<path fill="#333333" d="M5,8.5C3.07,8.5,1.5,6.93,1.5,5c0-1.93,1.57-3.5,3.5-3.5c1.93,0,3.5,1.57,3.5,3.5C8.5,6.93,6.93,8.5,5,8.5
-			L5,8.5z"/>
-		<path fill="#FFFFFF" d="M5,2c1.654,0,3,1.346,3,3c0,1.654-1.346,3-3,3C3.346,8,2,6.654,2,5C2,3.346,3.346,2,5,2 M5,1
-			C2.791,1,1,2.791,1,5s1.791,4,4,4s4-1.791,4-4S7.209,1,5,1L5,1z"/>
-	</g>
-</g>
-</svg>
--- themes/svg/icon-s-unselected-page.svg
+++ themes/svg/icon-s-unselected-page.svg
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="icon-s-unselected-page-layer"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="10px" height="10px"
-	 viewBox="0 0 10 10" style="enable-background:new 0 0 10 10;" xml:space="preserve">
-<g id="icon-s-unselected-page">
-	<rect style="fill:none;" width="10" height="10"/>
-	<g>
-		<path style="fill:#FFFFFF;" d="M5,8.5C3.07,8.5,1.5,6.93,1.5,5S3.07,1.5,5,1.5c1.93,0,3.5,1.57,3.5,3.5S6.93,8.5,5,8.5L5,8.5z"/>
-		<path style="fill:#333333;" d="M5,2c1.655,0,3,1.346,3,3S6.654,8,5,8C3.345,8,2,6.654,2,5S3.345,2,5,2 M5,1C2.79,1,1,2.791,1,5
-			S2.79,9,5,9s4-1.791,4-4S7.209,1,5,1L5,1z"/>
-	</g>
-</g>
-</svg>

++++++ meegotouch-home.desktop
--- meegotouch-home.desktop
+++ meegotouch-home.desktop
@@ -1,4 +1,4 @@
 [Desktop Entry]
 Exec=/usr/bin/duihome --desktop -remote-theme
 X-Moblin-Priority=Normal
-OnlyShowIn=X-DUI;
+OnlyShowIn=X-MEEGO-HS;

++++++ meegotouch-home.yaml
--- meegotouch-home.yaml
+++ meegotouch-home.yaml
@@ -1,6 +1,6 @@
 Name: meegotouch-home
 Summary: MeeGo Touch Homescreen
-Version: 0.21.9
+Version: 0.21.14
 Release: 1
 Group: System/Desktop
 License: LGPL v2.1
@@ -9,9 +9,11 @@
     - "%{name}-%{version}.tar.bz2"
     - meegotouch-home.desktop
 Patches:
-    - 0001-Modified-to-use-QIcon-to-load-application-icons-in-t.patch
     - duihome-0.21.9-Default-to-Detailview.patch
     - 0001-Remove-labels-from-QuickLaunchBarButtons.patch
+    - fix_unresolved_meegotouch_syms.patch
+    - comment_out_non-compiling_tests.patch
+    - fix_switcherbutton_compile.patch
 Description: The home screen for the MeeGo Touch environment
 
 PkgBR:
@@ -22,6 +24,7 @@
     - contextprovider-1.0
     - xcomposite
     - meegotouch
+    - contentaction-0.1
 
 Provides:
     - duihome >= 0.21.9

++++++ deleted files:
--- 0001-Modified-to-use-QIcon-to-load-application-icons-in-t.patch



More information about the MeeGo-commits mailing list