<div dir="ltr"><div>Hi,</div><div><br></div><div>I believe I've found a bug in snorenotify 0.7.0 that's inhibiting me from re-using existing notifications effectively.</div><div><br></div><div>The symptom I'm seeing is that I cannot update a notification more than 2 times before it stops issuing the updates I requested.</div><div><br></div><div>I have a piece of code that does the following</div><div><br></div>    bool needsNewNotification = !lastNotification.isValid() || lastNotification.closeReason() != Snore::Notification::CloseReasons::None;<br><br>    if (needsNewNotification) {<br>        qDebug() << "creating new notification";<br>        lastNotification = Snore::Notification{snoreApp, Snore::Alert(), title, message, snoreIcon, 0};<br>    }<br>    else {<br>        qDebug() << "reusing last notification";<br>        lastNotification = Snore::Notification{lastNotification, title, message, snoreIcon, 0};<br>    }<br><br><div>    notifyCore.broadcastNotification(lastNotification);</div><div><br></div><div>The rest isn't super important, the point here is that we try to reuse a notification when it's valid and hasn't been closed.</div><div><br></div><div>I looked into the snorenotify source and it looks like snorenotify is incrementing the active count on notification updates. In snoreCore::broadcastNotification m_activeNotifications is checked to see if it contains under 3 messages. If it does it adds the new notification to the queue until the previous ones have been closed.</div><div><br></div><div>
<pre><code>void SnoreCore::broadcastNotification(Notification notification)
{
    Q_D(SnoreCore);
    if (d->m_activeNotifications.size() > d->maxNumberOfActiveNotifications()) {
        qCDebug(SNORE) << "queue size:" << d->m_notificationQue.size() << "active size:" << d->m_activeNotifications.size();
        d->m_notificationQue.append(notification);
        return;
    }
    Q_ASSERT_X(!notification.data()->isBroadcasted(), Q_FUNC_INFO, "Notification was already broadcasted.");
    qCDebug(SNORE) << "Broadcasting" << notification << "timeout:" << notification.timeout();
    if (d->m_notificationBackend != nullptr) {
        if (notification.isUpdate() && !d->m_notificationBackend->canUpdateNotification()) {
            requestCloseNotification(notification.old(), Notification::Replaced);
        }
    }
    notification.data()->setBroadcasted();
    notification.addActiveIn(this);
    if (!d->m_notificationBackend) {
        d->startNotificationTimeoutTimer(notification);
    }
    emit d->notify(notification);
}</code></pre>

</div><div><br></div><div>The problem is that if the backend supports updating notifications nothing ties back the notification to the old one. In Notification::addActiveIn we add a notification with a new Id unconditionally. When creating a notification based on a previous one we always get a new ID</div><div><br></div><div>
<pre><code>Snore::NotificationData::NotificationData(const Notification &old, const QString &title, const QString &text, const Icon &icon, int timeout, Notification::Prioritys priority):
    m_id(m_idCount++),
    m_timeout(priority == Notification::Emergency ? 0 : timeout),
    m_application(old.application()),
    m_alert(old.alert()),
    m_title(title),
    m_text(text),
    m_icon(icon),
    m_priority(priority),
    m_hints(m_application.constHints()),
    m_toReplace(old)
{
    notificationCount++;
    qCDebug(SNORE) << "Creating Notification: ActiveNotifications" << notificationCount << "id" << m_id;
    qCDebug(SNORE) << title << text;
}</code></pre>

</div><div>Which is added to the map unconditionally at</div><div><br></div><div>
<pre><code>void Notification::addActiveIn(const QObject *o)
{
    bool contains = d->m_activeIn.contains(o);
    Q_ASSERT_X(!contains, Q_FUNC_INFO, "already active");
    if (contains) {
        qCWarning(SNORE) << o << "already active in" << id();
        return;
    }
    d->m_activeIn.insert(o);
    SnoreCorePrivate::instance()->m_activeNotifications[id()] = *this;
    qCDebug(SNORE) << SnoreCorePrivate::instance()->m_activeNotifications.size();
}</code></pre>

</div><div><br></div><div>I tried to work around it by manually issuing a close request myself and only handling close requests on my end if closeReason() != Replaced, however the closeReason() method is non-const, so I cannot check the closeReason() in the notificationClosed callback.</div><div><br></div><div>Thanks for your time,</div><div>MIck Sayson<br></div></div>