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(); }
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(); }