I have made the following changes intended for :
  CE:UX:MTF / lipstick

Please review and accept or decline.
BOSS has already run some checks on this request.
See the "Messages from BOSS" section below.

https://build.pub.meego.com//request/show/7218

Thank You,
Islam Amer

[This message was auto-generated]

---

Request # 7218:

Messages from BOSS:

State: review at 2012-10-31T12:48:03 by bossbot

Reviews:
       accepted by bossbot : Prechecks succeeded.
       new for CE-maintainers : Please replace this text with a review and 
approve/reject the review (not the SR). BOSS will take care of the rest

Changes:
  submit: Project:MTF:UX / lipstick -> CE:UX:MTF / lipstick
  
changes files:
--------------
--- lipstick.changes
+++ lipstick.changes
@@ -0,0 +1,3 @@
+* Wed Oct 31 2012 Vesa Halttunen <[email protected]> - 0.4.5
+- Support for notifications on top of all applications (from Vesa)
+

old:
----
  lipstick-0.4.4.tar.bz2

new:
----
  lipstick-0.4.5.tar.bz2

spec files:
-----------
--- lipstick.spec
+++ lipstick.spec
@@ -9,7 +9,7 @@
 # << macros
 
 Summary:    QML toolkit for homescreen creation
-Version:    0.4.4
+Version:    0.4.5
 Release:    1
 Group:      System/Libraries
 License:    LGPLv2.1
@@ -25,6 +25,8 @@
 BuildRequires:  pkgconfig(mlite) >= 0.0.6
 BuildRequires:  pkgconfig(xcomposite)
 BuildRequires:  pkgconfig(xdamage)
+BuildRequires:  pkgconfig(xfixes)
+BuildRequires:  pkgconfig(xext)
 
 %description
 A QML toolkit for homescreen creation

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

++++++ lipstick-0.4.4.tar.bz2 -> lipstick-0.4.5.tar.bz2
--- .gitignore
+++ .gitignore
@@ -1,18 +0,0 @@
-Makefile
-*.o
-*gen_*.h
-*gen_*.cpp
-*gen_*.o
-*moc_*.h
-*moc_*.cpp
-*moc_*.o
-*~
-*.log
-*.log.xml
-*.gcno
-*.gcda
-*.pro.user
-configure-stamp
-build-stamp
-.project
-.cproject
--- plugin/.gitignore
+++ plugin/.gitignore
@@ -1 +0,0 @@
-liblipstickplugin.so
--- plugin/lipstickplugin.cpp
+++ plugin/lipstickplugin.cpp
@@ -23,6 +23,7 @@
 #include <components/statusbar.h>
 #include <components/windowmanager.h>
 #include <components/windowinfo.h>
+#include <notifications/notificationpreviewpresenter.h>
 #include <notifications/notificationlistmodel.h>
 #include <notifications/notification.h>
 
@@ -41,6 +42,7 @@
     qmlRegisterType<StatusBar>("org.nemomobile.lipstick", 0, 1, "StatusBar");
     qmlRegisterType<NotificationListModel>("org.nemomobile.lipstick", 0, 1, 
"NotificationListModel");
     qmlRegisterType<Notification>("org.nemomobile.lipstick", 0, 1, 
"Notification");
+    
qmlRegisterUncreatableType<NotificationPreviewPresenter>("org.nemomobile.lipstick",
 0, 1, "NotificationPreviewPresenter", "This type is initialized by 
HomeApplication");
     qmlRegisterUncreatableType<WindowInfo>("org.nemomobile.lipstick", 0, 1, 
"WindowInfo", "This type is initialized by SwitcherModel");
     qmlRegisterUncreatableType<LauncherItem>("org.nemomobile.lipstick", 0, 1, 
"LauncherItem", "This type is initialized by LauncherModel");
     qmlRegisterUncreatableType<WindowManager>("org.nemomobile.lipstick", 0, 1, 
"WindowManager", "This type should be accessed through a context property.");
--- src/.gitignore
+++ src/.gitignore
@@ -1,2 +0,0 @@
-liblipstick.*
-pkgconfig
--- src/homeapplication.cpp
+++ src/homeapplication.cpp
@@ -33,6 +33,7 @@
 #include "xtools/xwindowmanager.h"
 #include "xtools/homewindowmonitor.h"
 #include "notifications/notificationmanager.h"
+#include "notifications/notificationpreviewpresenter.h"
 #include "components/windowmanager.h"
 #include "components/windowinfo.h"
 #include "lipsticksettings.h"
@@ -73,6 +74,7 @@
 
     // Initialize the notification manager;
     NotificationManager::instance();
+    new NotificationPreviewPresenter(this);
 
     // Initialize the home window monitor
     HomeWindowMonitor::instance();
--- src/notifications/.gitignore
+++ src/notifications/.gitignore
@@ -1 +0,0 @@
-notificationmanageradaptor.*
--- src/notifications/notificationpreviewpresenter.cpp
+++ src/notifications/notificationpreviewpresenter.cpp
@@ -0,0 +1,131 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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 <QApplication>
+#include <QDesktopWidget>
+#include <QDeclarativeView>
+#include <QDeclarativeContext>
+#include <QX11Info>
+#include <X11/extensions/shape.h>
+#include "xtools/x11wrapper.h"
+#include "notifications/notificationmanager.h"
+#include "notificationpreviewpresenter.h"
+
+NotificationPreviewPresenter::NotificationPreviewPresenter(QObject *parent) :
+    QObject(parent),
+    window(0),
+    currentNotification(0)
+{
+    connect(NotificationManager::instance(), 
SIGNAL(notificationModified(uint)), this, SLOT(updateNotification(uint)));
+    connect(NotificationManager::instance(), 
SIGNAL(notificationRemoved(uint)), this, SLOT(removeNotification(uint)));
+}
+
+void NotificationPreviewPresenter::showNextNotification()
+{
+    if (notificationQueue.isEmpty()) {
+        // No more notifications to show: hide the notification window if it's 
visible
+        if (window != 0 && window->isVisible()) {
+            window->hide();
+        }
+
+        currentNotification = 0;
+        emit notificationChanged();
+    } else {
+        // A notification to show: show the notification window and the first 
queued notification in it
+        createWindowIfNecessary();
+        if (!window->isVisible()) {
+            window->show();
+        }
+
+        currentNotification = notificationQueue.takeFirst();
+        emit notificationChanged();
+    }
+}
+
+Notification *NotificationPreviewPresenter::notification() const
+{
+    return currentNotification;
+}
+
+void NotificationPreviewPresenter::updateNotification(uint id)
+{
+    Notification *notification = 
NotificationManager::instance()->notification(id);
+    if (notificationShouldBeShown(notification)) {
+        // Add the notification to the queue if not already there or the 
current notification
+        if (currentNotification != notification && 
!notificationQueue.contains(notification)) {
+            notificationQueue.append(notification);
+
+            // Show the notification if no notification currently being shown
+            if (currentNotification == 0) {
+                showNextNotification();
+            }
+        }
+    } else {
+        removeNotification(id);
+    }
+}
+
+void NotificationPreviewPresenter::removeNotification(uint id)
+{
+    // Remove the notification from the queue
+    Notification *notification = 
NotificationManager::instance()->notification(id);
+
+    if (notification != 0) {
+        notificationQueue.removeAll(notification);
+
+        // If the notification is currently being shown hide it - the next 
notification will be shown after the current one has been hidden
+        if (currentNotification == notification) {
+            currentNotification = 0;
+            emit notificationChanged();
+        }
+    }
+}
+
+void NotificationPreviewPresenter::createWindowIfNecessary()
+{
+    if (window != 0) {
+        return;
+    }
+
+    window = new QDeclarativeView();
+    window->setAttribute(Qt::WA_TranslucentBackground);
+    window->setAttribute(Qt::WA_X11DoNotAcceptFocus);
+    window->setAttribute(Qt::WA_X11NetWmWindowTypeNotification);
+    window->setWindowTitle("Notification");
+    window->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+    window->viewport()->setAutoFillBackground(false);
+    window->rootContext()->setContextProperty("initialSize", 
QApplication::desktop()->screenGeometry(window).size());
+    window->rootContext()->setContextProperty("notificationPreviewPresenter", 
this);
+    window->setSource(QUrl("qrc:/qml/NotificationPreview.qml"));
+}
+
+bool NotificationPreviewPresenter::notificationShouldBeShown(Notification 
*notification)
+{
+    return !notification->previewBody().isEmpty() && 
!notification->previewSummary().isEmpty();
+}
+
+void NotificationPreviewPresenter::setNotificationPreviewRect(qreal x1, qreal 
y1, qreal x2, qreal y2)
+{
+    Display *dpy = QX11Info::display();
+    XRectangle rect;
+    rect.x = x1 < x2 ? x1 : x2;
+    rect.y = y1 < y2 ? y1 : y2;
+    rect.width = x1 < x2 ? (x2 - x1) : (x1 - x2);
+    rect.height = y1 < y2 ? (y2 - y1) : (y1 - y2);
+    XserverRegion shapeRegion = X11Wrapper::XFixesCreateRegion(dpy, &rect, 1);
+    X11Wrapper::XFixesSetWindowShapeRegion(dpy, window->winId(), ShapeInput, 
0, 0, shapeRegion);
+    X11Wrapper::XFixesDestroyRegion(dpy, shapeRegion);
+    X11Wrapper::XSync(dpy, False);
+}
--- src/notifications/notificationpreviewpresenter.h
+++ src/notifications/notificationpreviewpresenter.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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 NOTIFICATIONPREVIEWPRESENTER_H
+#define NOTIFICATIONPREVIEWPRESENTER_H
+
+#include "lipstickglobal.h"
+#include <QObject>
+
+class QDeclarativeView;
+class Notification;
+
+/*!
+ * \class NotificationManager
+ *
+ * \brief Presents notification previews one at a time.
+ *
+ * Creates a transparent notification window which can be used to show
+ * notification previews.
+ */
+class LIPSTICK_EXPORT NotificationPreviewPresenter : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(Notification *notification READ notification NOTIFY 
notificationChanged)
+
+public:
+    /*!
+     * Creates a notification preview presenter.
+     *
+     * \param parent the parent object
+     */
+    explicit NotificationPreviewPresenter(QObject *parent = 0);
+
+    /*!
+     * Sets the notification window's shape region according to the given
+     * coordinates. The coordinates should be set to match the coordinates of
+     * the notification preview in the window. This allows input events to be
+     * caught only on the notification preview area and passed through to the
+     * underneath window otherwise.
+     *
+     * \param x1 the X coordinate of the top left edge of the notification 
preview
+     * \param y1 the Y coordinate of the top left edge of the notification 
preview
+     * \param x2 the X coordinate of the bottom right edge of the notification 
preview
+     * \param y2 the Y coordinate of the bottom right edge of the notification 
preview
+     */
+    Q_INVOKABLE void setNotificationPreviewRect(qreal x1, qreal y1, qreal x2, 
qreal y2);
+    
+    /*!
+     * Returns the notification to be currently shown or 0 if no notification
+     * should be shown.
+     *
+     * \return the notification to be currently shown or 0 if no notification 
should be shown
+     */
+    Notification *notification() const;
+
+signals:
+    //! Sent when the notification to be shown has changed.
+    void notificationChanged();
+
+public slots:
+    /*!
+     * Shows the next notification to be shown, if any. If the notification
+     * window is not yet visible, shows the window. If there is no
+     * notification to be shown but the window is visible, hides the window.
+     */
+    void showNextNotification();
+
+private slots:
+    /*!
+     * Updates the notification with the given ID.
+     *
+     * \param id the ID of the notification to be updated
+     */
+    void updateNotification(uint id);
+
+    /*!
+     * Removes the notification with the given ID.
+     *
+     * \param id the ID of the notification to be removed
+     */
+    void removeNotification(uint id);
+
+private:
+    //! Creates the notification window if it has not been created yet.
+    void createWindowIfNecessary();
+
+    //! Checks whether the given notification has a preview body and a preview 
summary.
+    static bool notificationShouldBeShown(Notification *notification);
+
+    //! The notification window
+    QDeclarativeView *window;
+
+    //! Notifications to be shown
+    QList<Notification *> notificationQueue;
+
+    //! Notification currently being shown
+    Notification *currentNotification;
+
+#ifdef UNIT_TEST
+    friend class Ut_NotificationPreviewPresenter;
+#endif
+};
+
+#endif // NOTIFICATIONPREVIEWPRESENTER_H
--- src/src.pro
+++ src/src.pro
@@ -2,7 +2,7 @@
 
 TEMPLATE = lib
 TARGET = lipstick
-VERSION = 0.4.4
+VERSION = 0.4.5
 
 DEFINES += LIPSTICK_BUILD_LIBRARY DEBUG_NOTIFICATIONS
 
@@ -26,7 +26,8 @@
     components/windowmanager.h \
     notifications/notificationmanager.h \
     notifications/notification.h \
-    notifications/notificationlistmodel.h
+    notifications/notificationlistmodel.h \
+    notifications/notificationpreviewpresenter.h
 
 INSTALLS += publicheaderfiles
 publicheaderfiles.files = $$PUBLICHEADERS
@@ -40,6 +41,7 @@
     xtools/xeventlistener.h \
     xtools/xatomcache.h \
     xtools/xwindowmanager.h \
+    xtools/x11wrapper.h \
     lipstickdbusinterface.h \
     lipsticksettings.h \
     notifications/notificationmanager.h \
@@ -57,6 +59,7 @@
     xtools/xeventlistener.cpp \
     xtools/xatomcache.cpp \
     xtools/xwindowmanager.cpp \
+    xtools/x11wrapper.cpp \
     components/windowinfo.cpp \
     components/launcheritem.cpp \
     components/launchermodel.cpp \
@@ -68,11 +71,12 @@
     notifications/notificationmanageradaptor.cpp \
     notifications/notification.cpp \
     notifications/categorydefinitionstore.cpp \
-    notifications/notificationlistmodel.cpp
+    notifications/notificationlistmodel.cpp \
+    notifications/notificationpreviewpresenter.cpp
 
 CONFIG += link_pkgconfig mobility qt warn_on depend_includepath qmake_cache 
target_qt
 MOBILITY += sensors
-PKGCONFIG += xcomposite mlite xdamage x11
+PKGCONFIG += xcomposite mlite xdamage x11 xfixes xext
 
 packagesExist(contentaction-0.1) {
     message("Using contentaction to launch applications")
--- src/xtools/x11wrapper.cpp
+++ src/xtools/x11wrapper.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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 "x11wrapper.h"
+
+int X11Wrapper::XSync(Display *display, Bool discard)
+{
+    return ::XSync(display, discard);
+}
+
+XserverRegion X11Wrapper::XFixesCreateRegion(Display *dpy, XRectangle 
*rectangles, int nrectangles)
+{
+    return ::XFixesCreateRegion(dpy, rectangles, nrectangles);
+}
+
+void X11Wrapper::XFixesSetWindowShapeRegion(Display *dpy, Window win, int 
shape_kind, int x_off, int y_off, XserverRegion region)
+{
+    ::XFixesSetWindowShapeRegion(dpy, win, shape_kind, x_off, y_off, region);
+}
+
+void X11Wrapper::XFixesDestroyRegion(Display *dpy, XserverRegion region)
+{
+    ::XFixesDestroyRegion(dpy, region);
+}
--- src/xtools/x11wrapper.h
+++ src/xtools/x11wrapper.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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 X11WRAPPER_H_
+#define X11WRAPPER_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xfixes.h>
+
+class X11Wrapper
+{
+public:
+    static int XSync(Display *display, Bool discard);
+    static XserverRegion XFixesCreateRegion(Display *dpy, XRectangle 
*rectangles, int nrectangles);
+    static void XFixesSetWindowShapeRegion(Display *dpy, Window win, int 
shape_kind, int x_off, int y_off, XserverRegion region);
+    static void XFixesDestroyRegion(Display *dpy, XserverRegion region);
+};
+
+#endif /* X11WRAPPER_H_ */
--- tests/tests.pro
+++ tests/tests.pro
@@ -1,5 +1,5 @@
 TEMPLATE = subdirs
-SUBDIRS = ut_categorydefinitionstore ut_notification ut_notificationmanager 
ut_notificationlistmodel ut_lipstickdbusinterface ut_lipsticksettings
+SUBDIRS = ut_categorydefinitionstore ut_notification ut_notificationmanager 
ut_notificationlistmodel ut_lipstickdbusinterface ut_lipsticksettings 
ut_notificationpreviewpresenter
 
 support_files.commands += $$PWD/gen-tests-xml.sh > $$OUT_PWD/tests.xml
 support_files.target = support_files
--- tests/ut_categorydefinitionstore/.gitignore
+++ tests/ut_categorydefinitionstore/.gitignore
@@ -1 +0,0 @@
-ut_categorydefinitionstore
--- tests/ut_lipstickdbusinterface/.gitignore
+++ tests/ut_lipstickdbusinterface/.gitignore
@@ -1 +0,0 @@
-ut_lipstickdbusinterface
--- tests/ut_lipsticksettings/.gitignore
+++ tests/ut_lipsticksettings/.gitignore
@@ -1 +0,0 @@
-ut_lipsticksettings
--- tests/ut_notification/.gitignore
+++ tests/ut_notification/.gitignore
@@ -1 +0,0 @@
-ut_notification
--- tests/ut_notificationlistmodel/.gitignore
+++ tests/ut_notificationlistmodel/.gitignore
@@ -1 +0,0 @@
-ut_notificationlistmodel
--- tests/ut_notificationmanager/.gitignore
+++ tests/ut_notificationmanager/.gitignore
@@ -1 +0,0 @@
-ut_notificationmanager
--- tests/ut_notificationpreviewpresenter
+++ tests/ut_notificationpreviewpresenter
+(directory)
--- tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.cpp
+++ tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.cpp
@@ -0,0 +1,375 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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 <QDeclarativeView>
+#include <QDeclarativeContext>
+#include <QDesktopWidget>
+#include "notificationmanager.h"
+#include "ut_notificationpreviewpresenter.h"
+#include "notificationpreviewpresenter.h"
+#include "xtools/x11wrapper.h"
+#include <X11/extensions/shape.h>
+
+Q_DECLARE_METATYPE(NotificationPreviewPresenter*)
+Q_DECLARE_METATYPE(Notification*)
+
+QList<XRectangle> xFixesCreateRegionRectangles;
+XserverRegion X11Wrapper::XFixesCreateRegion(Display *, XRectangle 
*rectangles, int nrectangles)
+{
+    for (int i = 0; i < nrectangles; i++) {
+        xFixesCreateRegionRectangles.append(rectangles[i]);
+    }
+    return 1;
+}
+
+QList<Window> xFixesSetWindowShapeRegionWindow;
+QList<int> xFixesSetWindowShapeRegionShapeKind;
+QList<int> xFixesSetWindowShapeRegionXOff;
+QList<int> xFixesSetWindowShapeRegionYOff;
+QList<XserverRegion> xFixesSetWindowShapeRegionRegion;
+void X11Wrapper::XFixesSetWindowShapeRegion(Display *, Window win, int 
shape_kind, int x_off, int y_off, XserverRegion region)
+{
+    xFixesSetWindowShapeRegionWindow.append(win);
+    xFixesSetWindowShapeRegionShapeKind.append(shape_kind);
+    xFixesSetWindowShapeRegionXOff.append(x_off);
+    xFixesSetWindowShapeRegionYOff.append(y_off);
+    xFixesSetWindowShapeRegionRegion.append(region);
+}
+
+QList<XserverRegion> xFixesDestroyRegionRegion;
+void X11Wrapper::XFixesDestroyRegion(Display *, XserverRegion region)
+{
+    xFixesDestroyRegionRegion.append(region);
+}
+
+bool xSyncCalled = false;
+int X11Wrapper::XSync(Display *, int)
+{
+    xSyncCalled = true;
+    return 0;
+}
+
+QList<QDeclarativeView *> qDeclarativeViews;
+void QDeclarativeView::setSource(const QUrl &)
+{
+    qDeclarativeViews.append(this);
+}
+
+QHash<QWidget *, bool> qWidgetVisible;
+void QWidget::setVisible(bool visible)
+{
+    setAttribute(Qt::WA_WState_Visible, visible);
+    qWidgetVisible[this] = visible;
+}
+
+const char *NotificationManager::HINT_ICON = "x-nemo-icon";
+const char *NotificationManager::HINT_TIMESTAMP = "x-nemo-timestamp";
+const char *NotificationManager::HINT_PREVIEW_ICON = "x-nemo-preview-icon";
+const char *NotificationManager::HINT_PREVIEW_BODY = "x-nemo-preview-body";
+const char *NotificationManager::HINT_PREVIEW_SUMMARY = 
"x-nemo-preview-summary";
+
+NotificationManager::NotificationManager(QObject *parent) : QObject(parent)
+{
+}
+
+NotificationManager::~NotificationManager()
+{
+}
+
+void NotificationManager::invokeAction(const QString &)
+{
+}
+
+void NotificationManager::removeNotificationsWithCategory(const QString &)
+{
+}
+
+void NotificationManager::updateNotificationsWithCategory(const QString &)
+{
+}
+
+void NotificationManager::commit()
+{
+}
+
+NotificationManager *notificationManagerInstance = 0;
+NotificationManager *NotificationManager::instance()
+{
+    if (notificationManagerInstance == 0) {
+        notificationManagerInstance = new NotificationManager;
+    }
+    return notificationManagerInstance;
+}
+
+QHash<uint, Notification *> notificationManagerNotification;
+Notification *NotificationManager::notification(uint id) const
+{
+    return notificationManagerNotification.value(id);
+}
+
+Notification *createNotification(uint id)
+{
+    Notification *notification = new Notification;
+    QVariantHash hints;
+    hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, "summary");
+    hints.insert(NotificationManager::HINT_PREVIEW_BODY, "body");
+    notification->setHints(hints);
+    notificationManagerNotification.insert(id, notification);
+    return notification;
+}
+
+void Ut_NotificationPreviewPresenter::initTestCase()
+{
+    qRegisterMetaType<Notification *>();
+    NotificationManager::instance()->setParent(this);
+}
+
+void Ut_NotificationPreviewPresenter::cleanup()
+{
+    qDeclarativeViews.clear();
+    qWidgetVisible.clear();
+    qDeleteAll(notificationManagerNotification);
+    notificationManagerNotification.clear();
+}
+
+void Ut_NotificationPreviewPresenter::testSignalConnections()
+{
+    NotificationPreviewPresenter presenter;
+    QCOMPARE(disconnect(NotificationManager::instance(), 
SIGNAL(notificationModified(uint)), &presenter, 
SLOT(updateNotification(uint))), true);
+    QCOMPARE(disconnect(NotificationManager::instance(), 
SIGNAL(notificationRemoved(uint)), &presenter, SLOT(removeNotification(uint))), 
true);
+}
+
+void Ut_NotificationPreviewPresenter::testAddNotificationWhenWindowNotOpen()
+{
+    NotificationPreviewPresenter presenter;
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+
+    // Check that the window is not automatically created
+    QCOMPARE(qDeclarativeViews.isEmpty(), true);
+
+    // Check that the window is created when a notification is added
+    Notification *notification = createNotification(1);
+    presenter.updateNotification(1);
+    QCOMPARE(qDeclarativeViews.count(), 1);
+
+    // Check window properties
+    
QCOMPARE(qDeclarativeViews.first()->testAttribute(Qt::WA_TranslucentBackground),
 true);
+    
QCOMPARE(qDeclarativeViews.first()->testAttribute(Qt::WA_X11DoNotAcceptFocus), 
true);
+    
QCOMPARE(qDeclarativeViews.first()->testAttribute(Qt::WA_X11NetWmWindowTypeNotification),
 true);
+    QCOMPARE(qDeclarativeViews.first()->windowTitle(), 
QString("Notification"));
+    QCOMPARE(qDeclarativeViews.first()->resizeMode(), 
QDeclarativeView::SizeRootObjectToView);
+    QCOMPARE(qDeclarativeViews.first()->viewport()->autoFillBackground(), 
false);
+    
QCOMPARE(qDeclarativeViews.first()->rootContext()->contextProperty("initialSize").toSize(),
 QApplication::desktop()->screenGeometry(qDeclarativeViews.first()).size());
+    
QCOMPARE(qDeclarativeViews.first()->rootContext()->contextProperty("notificationPreviewPresenter"),
 QVariant::fromValue(static_cast<QObject *>(&presenter)));
+
+    // Check that the window was shown
+    QCOMPARE(qWidgetVisible[static_cast<QWidget 
*>(qDeclarativeViews.first())], true);
+
+    // Check that the expected notification is signaled onwards
+    QCOMPARE(spy.count(), 1);
+    QCOMPARE(presenter.notification(), notification);
+}
+
+void 
Ut_NotificationPreviewPresenter::testAddNotificationWhenWindowAlreadyOpen()
+{
+    NotificationPreviewPresenter presenter;
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+
+    // Create a notification: this will create a window
+    createNotification(1);
+    presenter.updateNotification(1);
+
+    // Reset stubs to see what happens next
+    qDeclarativeViews.clear();
+
+    // Create another notification
+    Notification *notification = createNotification(2);
+    presenter.updateNotification(2);
+
+    // The second notification should not be signaled onwards yet since the 
first one is being presented
+    QCOMPARE(spy.count(), 1);
+
+    // Show the next notification
+    presenter.showNextNotification();
+
+    // Check that the window was not unnecessarily created again
+    QCOMPARE(qDeclarativeViews.isEmpty(), true);
+
+    // Check that the expected notification is signaled onwards
+    QCOMPARE(spy.count(), 2);
+    QCOMPARE(presenter.notification(), notification);
+}
+
+void Ut_NotificationPreviewPresenter::testUpdateNotification()
+{
+    NotificationPreviewPresenter presenter;
+
+    // Create two notifications
+    createNotification(1);
+    createNotification(2);
+    presenter.updateNotification(1);
+    presenter.updateNotification(2);
+
+    // Update both notifications
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+    presenter.updateNotification(1);
+    presenter.updateNotification(2);
+
+    // Check that no signals were sent
+    QCOMPARE(spy.count(), 0);
+}
+
+void Ut_NotificationPreviewPresenter::testRemoveNotification()
+{
+    NotificationPreviewPresenter presenter;
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+
+    // Create two notifications
+    createNotification(1);
+    createNotification(2);
+    presenter.updateNotification(1);
+    presenter.updateNotification(2);
+
+    // Remove the first one
+    presenter.removeNotification(1);
+
+    // Check that an empty notification is signaled onwards
+    QCOMPARE(spy.count(), 2);
+    QCOMPARE(presenter.notification(), (Notification *)0);
+
+    // Show and remove the second one
+    presenter.showNextNotification();
+    presenter.removeNotification(2);
+
+    // Check that an empty notification is signaled onwards
+    QCOMPARE(spy.count(), 4);
+    QCOMPARE(presenter.notification(), (Notification *)0);
+
+    // Check that the window is not yet hidden
+    QCOMPARE(qWidgetVisible[static_cast<QWidget 
*>(qDeclarativeViews.first())], true);
+
+    // Check that the window is hidden when it's time to show the next 
notification (which doesn't exist)
+    presenter.showNextNotification();
+    QCOMPARE(qWidgetVisible[static_cast<QWidget 
*>(qDeclarativeViews.first())], false);
+}
+
+void Ut_NotificationPreviewPresenter::testWindowMasking_data()
+{
+    QTest::addColumn<int>("x1");
+    QTest::addColumn<int>("y1");
+    QTest::addColumn<int>("x2");
+    QTest::addColumn<int>("y2");
+    QTest::addColumn<int>("x");
+    QTest::addColumn<int>("y");
+    QTest::addColumn<int>("width");
+    QTest::addColumn<int>("height");
+    QTest::newRow("x1  < x2, y1  < y2") << 10 << 10 << 50 << 50 << 10 << 10 << 
40 << 40;
+    QTest::newRow("x1 >= x2, y1  < y2") << 50 << 10 << 10 << 50 << 10 << 10 << 
40 << 40;
+    QTest::newRow("x1  < x2, y1 >= y2") << 10 << 50 << 50 << 10 << 10 << 10 << 
40 << 40;
+    QTest::newRow("x1 >= x2, y1 >= y2") << 50 << 50 << 10 << 10 << 10 << 10 << 
40 << 40;
+}
+
+void Ut_NotificationPreviewPresenter::testWindowMasking()
+{
+    QFETCH(int, x1);
+    QFETCH(int, y1);
+    QFETCH(int, x2);
+    QFETCH(int, y2);
+    QFETCH(int, x);
+    QFETCH(int, y);
+    QFETCH(int, width);
+    QFETCH(int, height);
+    NotificationPreviewPresenter presenter;
+
+    // Check that the window is created when a notification is added
+    createNotification(1);
+    presenter.updateNotification(1);
+    presenter.setNotificationPreviewRect(x1, y1, x2, y2);
+
+    QRect rect(x, y, width, height);
+    QCOMPARE(xFixesCreateRegionRectangles.isEmpty(), false);
+    QCOMPARE(xFixesCreateRegionRectangles.last().x, (short)rect.x());
+    QCOMPARE(xFixesCreateRegionRectangles.last().y, (short)rect.y());
+    QCOMPARE(xFixesCreateRegionRectangles.last().width, (unsigned 
short)rect.width());
+    QCOMPARE(xFixesCreateRegionRectangles.last().height, (unsigned 
short)rect.height());
+    QCOMPARE(xFixesSetWindowShapeRegionWindow.isEmpty(), false);
+    QCOMPARE(xFixesSetWindowShapeRegionWindow.last(), 
qDeclarativeViews.first()->winId());
+    QCOMPARE(xFixesSetWindowShapeRegionShapeKind.last(), ShapeInput);
+    QCOMPARE(xFixesSetWindowShapeRegionXOff.last(), 0);
+    QCOMPARE(xFixesSetWindowShapeRegionYOff.last(), 0);
+    QCOMPARE(xFixesSetWindowShapeRegionRegion.last(), (XserverRegion)1);
+    QCOMPARE(xFixesDestroyRegionRegion.isEmpty(), false);
+    QCOMPARE(xFixesDestroyRegionRegion.last(), (XserverRegion)1);
+    QCOMPARE(xSyncCalled, true);
+}
+
+void 
Ut_NotificationPreviewPresenter::testNotificationNotShownIfNoSummaryOrBody_data()
+{
+    QTest::addColumn<QString>("previewSummary");
+    QTest::addColumn<QString>("previewBody");
+    QTest::addColumn<int>("signalCount");
+    QTest::addColumn<bool>("windowVisible");
+    QTest::newRow("No summary, no body") << "" << "" << 0 << false;
+    QTest::newRow("Summary, no body") << "summary" << "" << 0 << false;
+    QTest::newRow("No summary, body") << "" << "body" << 0 << false;
+    QTest::newRow("Summary, body") << "summary" << "body" << 1 << true;
+}
+
+void 
Ut_NotificationPreviewPresenter::testNotificationNotShownIfNoSummaryOrBody()
+{
+    QFETCH(QString, previewSummary);
+    QFETCH(QString, previewBody);
+    QFETCH(int, signalCount);
+    QFETCH(bool, windowVisible);
+
+    NotificationPreviewPresenter presenter;
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+
+    // Create notification
+    Notification *notification = new Notification;
+    QVariantHash hints;
+    hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, previewSummary);
+    hints.insert(NotificationManager::HINT_PREVIEW_BODY, previewBody);
+    notification->setHints(hints);
+    notificationManagerNotification.insert(1, notification);
+    presenter.updateNotification(1);
+
+    // Check whether the expected notification is signaled onwards
+    QCOMPARE(spy.count(), signalCount);
+
+    // Check whether the window was shown
+    QCOMPARE(qWidgetVisible[static_cast<QWidget 
*>(qDeclarativeViews.first())], windowVisible);
+}
+
+void 
Ut_NotificationPreviewPresenter::testUpdateNotificationRemovesNotificationIfNoSummaryOrBody()
+{
+    NotificationPreviewPresenter presenter;
+
+    // Create a notification
+    Notification *notification = createNotification(1);
+    presenter.updateNotification(1);
+
+    // Update the notification to have no summary or body
+    QSignalSpy spy(&presenter, SIGNAL(notificationChanged()));
+    notification->setHints(QVariantHash());
+    presenter.updateNotification(1);
+
+    // Check that an empty notification is signaled onwards
+    QCOMPARE(spy.count(), 1);
+    QCOMPARE(presenter.notification(), (Notification *)0);
+}
+
+QTEST_MAIN(Ut_NotificationPreviewPresenter)
--- tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.h
+++ tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Jolla Ltd.
+** Contact: Robin Burchell <[email protected]>
+**
+** This file is part of lipstick.
+**
+** 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_NOTIFICATIONPREVIEWPRESENTER_H
+#define UT_NOTIFICATIONPREVIEWPRESENTER_H
+
+#include <QObject>
+
+class Ut_NotificationPreviewPresenter : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+    void cleanup();
+    void testSignalConnections();
+    void testAddNotificationWhenWindowNotOpen();
+    void testAddNotificationWhenWindowAlreadyOpen();
+    void testUpdateNotification();
+    void testRemoveNotification();
+    void testWindowMasking_data();
+    void testWindowMasking();
+    void testNotificationNotShownIfNoSummaryOrBody_data();
+    void testNotificationNotShownIfNoSummaryOrBody();
+    void testUpdateNotificationRemovesNotificationIfNoSummaryOrBody();
+};
+
+#endif
--- tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.pro
+++ tests/ut_notificationpreviewpresenter/ut_notificationpreviewpresenter.pro
@@ -0,0 +1,17 @@
+include(../common.pri)
+TARGET = ut_notificationpreviewpresenter
+INCLUDEPATH += $$SRCDIR $$NOTIFICATIONSRCDIR
+QT += declarative dbus
+
+# unit test and unit
+SOURCES += \
+    ut_notificationpreviewpresenter.cpp \
+    $$NOTIFICATIONSRCDIR/notificationpreviewpresenter.cpp \
+    $$NOTIFICATIONSRCDIR/notification.cpp
+
+# unit test and unit
+HEADERS += \
+    ut_notificationpreviewpresenter.h \
+    $$NOTIFICATIONSRCDIR/notificationpreviewpresenter.h \
+    $$NOTIFICATIONSRCDIR/notificationmanager.h \
+    $$NOTIFICATIONSRCDIR/notification.h
--- tools/notificationtool/.gitignore
+++ tools/notificationtool/.gitignore
@@ -1,2 +0,0 @@
-notificationmanagerproxy.*
-notificationtool

++++++ lipstick.yaml
--- lipstick.yaml
+++ lipstick.yaml
@@ -1,6 +1,6 @@
 Name: lipstick
 Summary: QML toolkit for homescreen creation
-Version: 0.4.4
+Version: 0.4.5
 Release: 1
 Group: System/Libraries
 License: LGPLv2.1
@@ -17,6 +17,8 @@
     - mlite >= 0.0.6
     - xcomposite
     - xdamage
+    - xfixes
+    - xext
 Files:
     - "%{_libdir}/liblipstick.so.*"
     - "%{_libdir}/qt4/imports/org/nemomobile/lipstick/liblipstickplugin.so"



Reply via email to