NotificationArea::NotificationArea(QWidget *parent)
    : QScrollArea(parent),
      m_spacing(-1)
{
    setObjectName("NotificationArea");

    setWindowFlags(Qt::X11BypassWindowManagerHint
                   | Qt::FramelessWindowHint
                   | Qt::WindowStaysOnTopHint);
    // Hack to ensure the fully transparent QGraphicsView background
    QPalette palette;
    palette.setBrush(QPalette::Base, Qt::NoBrush);
    setPalette(palette);
    // Required to display wallpaper
    setAttribute(Qt::WA_TranslucentBackground);
    // no border at all finally
    setFrameShape(QFrame::NoFrame);

    m_layout = new NotificationLayout(this);
    setWidget(m_layout);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    connect(m_layout, SIGNAL(allNotificationsClosed()), this, SLOT(close()));
    connect(m_layout, SIGNAL(notificationAvailable()), this, SLOT(show()));
    connect(m_layout, SIGNAL(heightChanged(int)), this, SLOT(setHeight(int)));
}
void NotificationLayout::addNotification(uint id, const QString &application,
                                        const QString &summary, const QString &body,
                                        const QString &icon, int timeout,
                                        const QStringList& actions, const QVariantMap& hints)
{
//    qDebug() << "NotificationLayout::addNotification" << id << application << summary << body << icon << timeout;
    if (m_notifications.contains(id))
    {
        // TODO/FIXME: it can be deleted by timer in this block. Locking?
        Notification *n = m_notifications[id];
        n->setValues(application, summary, body, icon, timeout, actions, hints);
    }
    else
    {
        Notification *n = new Notification(application, summary, body, icon, timeout, actions, hints, this);

        // NOTE: it's hard to use == operator for Notification* in QList...
        QHashIterator<uint, Notification*> it(m_notifications);
        while (it.hasNext())
        {
            it.next();
            if (it.value()->application() == application
                    && it.value()->summary() == summary
                    && it.value()->body() == body)
            {
                qDebug() << "Notification app" << application << "summary" << summary << "is already registered but this request is not an update. Broken app?";
                delete n;
                return;
            }
        }

        connect(n, &Notification::timeout, this, &NotificationLayout::removeNotificationTimeout);
        connect(n, &Notification::userCanceled, this, &NotificationLayout::removeNotificationUser);
        connect(n, &Notification::actionTriggered,
                this, &NotificationLayout::notificationActionCalled);
        m_notifications[id] = n;
        m_layout->addWidget(n);
        n->show();
    }

    checkHeight();
    emit notificationAvailable();

    // NOTE by pcman:
    // This dirty hack is used to workaround a weird and annoying repainting bug caused by Qt.
    // See https://github.com/Razor-qt/razor-qt/issues/536
    // razot-qt bug #536 - Notifications do not repaint under certain conditions
    // When we create the first notification and are about to show the widget, force repaint() here.
    // FIXME: there should be better ways to do this, or it should be fixed in Qt instead.
    if(m_notifications.count() == 1)
        repaint();
}
Example #3
0
void NotificationLayout::addNotification(uint id, const QString &application,
                                        const QString &summary, const QString &body,
                                        const QString &icon, int timeout,
                                        const QStringList& actions, const QVariantMap& hints)
{
//    qDebug() << "NotificationLayout::addNotification" << id << application << summary << body << icon << timeout;
    if (m_notifications.contains(id))
    {
        // TODO/FIXME: it can be deleted by timer in this block. Locking?
        Notification *n = m_notifications[id];
        n->setValues(application, summary, body, icon, timeout, actions, hints);
    }
    else
    {
        Notification *n = new Notification(application, summary, body, icon, timeout, actions, hints, this);

        // NOTE: it's hard to use == operator for Notification* in QList...
        QHashIterator<uint, Notification*> it(m_notifications);
        while (it.hasNext())
        {
            it.next();
            if (it.value()->application() == application
                    && it.value()->summary() == summary
                    && it.value()->body() == body)
            {
                qDebug() << "Notification app" << application << "summary" << summary << "is already registered but this request is not an update. Broken app?";
                delete n;
                return;
            }
        }

        connect(n, SIGNAL(timeout()), this, SLOT(removeNotificationTimeout()));
        connect(n, SIGNAL(userCanceled()), this, SLOT(removeNotificationUser()));
        connect(n, SIGNAL(actionTriggered(QString)),
                this, SLOT(notificationActionCalled(QString)));
        m_notifications[id] = n;
        m_layout->addWidget(n);
        n->show();
    }

    emit notificationAvailable();
    checkHeight();
}