Commit 55400729 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇

[Notifications] Sort popups ascending

This ensures that newer notification popups don't push old ones out.
Some applications are notorious for spamming the user which right now results in a firework
of notification popups. With this patch only the number that fits on screen is displayed and
everything beyond that is off screen until there's enough room for new popups which are
then gradually lowered.

It also reduces the likelihood of the notification the user is interacting with being shifted
away by an incoming notification. Furthermore, since notifications that are off screen will
have their timeout reset, it can happen that you have a bunch of recent notifications at the
bottom but then get some old ones that were off screen sliding back in because some middle ones
have expired already, leading to awkward results.

Notification scoring (e.g. critical before normal) is untouched, so a "battery is critical" notification
will show up even if it's still chugging through the backlog of browser notifications.

Differential Revision: https://phabricator.kde.org/D28646
parent 96ad51cd
......@@ -329,6 +329,7 @@ QtObject {
whitelistedNotifyRcNames: globals.inhibited ? notificationSettings.doNotDisturbPopupWhitelistedServices : []
showJobs: notificationSettings.jobsInNotifications
sortMode: NotificationManager.Notifications.SortByTypeAndUrgency
sortOrder: Qt.AscendingOrder
groupMode: NotificationManager.Notifications.GroupDisabled
urgencies: {
var urgencies = 0;
......
......@@ -209,6 +209,7 @@ void Notifications::Private::initProxyModels()
if (!sortModel) {
sortModel = new NotificationSortProxyModel(q);
connect(sortModel, &NotificationSortProxyModel::sortModeChanged, q, &Notifications::sortModeChanged);
connect(sortModel, &NotificationSortProxyModel::sortOrderChanged, q, &Notifications::sortOrderChanged);
}
if (!limiterModel) {
......@@ -572,6 +573,16 @@ void Notifications::setSortMode(SortMode sortMode)
d->sortModel->setSortMode(sortMode);
}
Qt::SortOrder Notifications::sortOrder() const
{
return d->sortModel->sortOrder();
}
void Notifications::setSortOrder(Qt::SortOrder sortOrder)
{
d->sortModel->setSortOrder(sortOrder);
}
Notifications::GroupMode Notifications::groupMode() const
{
return d->groupMode;
......
......@@ -140,6 +140,20 @@ class NOTIFICATIONMANAGER_EXPORT Notifications : public QSortFilterProxyModel, p
*/
Q_PROPERTY(SortMode sortMode READ sortMode WRITE setSortMode NOTIFY sortModeChanged)
/**
* The sort order for notifications.
*
* This only affects the sort order by date. When @c sortMode is set to SortByTypeAndUrgency
* the order of notification groups (e.g. high - jobs - normal - low) is unaffected, and only
* notifications within the same group are either sorted ascending or descending by their
* creation/update date.
*
* Default is DescendingOrder, i.e. newest notifications come first.
*
* @since 5.19
*/
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
/**
* The group mode for notifications.
*
......@@ -368,6 +382,9 @@ public:
SortMode sortMode() const;
void setSortMode(SortMode sortMode);
Qt::SortOrder sortOrder() const;
void setSortOrder(Qt::SortOrder sortOrder);
GroupMode groupMode() const;
void setGroupMode(GroupMode groupMode);
......@@ -516,6 +533,7 @@ signals:
void showJobsChanged();
void urgenciesChanged();
void sortModeChanged();
void sortOrderChanged();
void groupModeChanged();
void groupLimitChanged();
void expandUnreadChanged();
......
......@@ -50,6 +50,20 @@ void NotificationSortProxyModel::setSortMode(Notifications::SortMode sortMode)
}
}
Qt::SortOrder NotificationSortProxyModel::sortOrder() const
{
return m_sortOrder;
}
void NotificationSortProxyModel::setSortOrder(Qt::SortOrder sortOrder)
{
if (m_sortOrder != sortOrder) {
m_sortOrder = sortOrder;
invalidate();
emit sortOrderChanged();
}
}
int sortScore(const QModelIndex &idx)
{
const auto urgency = idx.data(Notifications::UrgencyRole).toInt();
......@@ -109,8 +123,11 @@ bool NotificationSortProxyModel::lessThan(const QModelIndex &source_left, const
timeRight = source_right.data(Notifications::CreatedRole).toDateTime();
}
// sorts descending by time (newest first)
return timeLeft > timeRight;
if (m_sortOrder == Qt::DescendingOrder) {
return timeLeft > timeRight;
} else {
return timeLeft < timeRight;
}
}
return scoreLeft > scoreRight;
......
......@@ -39,14 +39,19 @@ public:
Notifications::SortMode sortMode() const;
void setSortMode(Notifications::SortMode);
Qt::SortOrder sortOrder() const;
void setSortOrder(Qt::SortOrder sortOrder);
signals:
void sortModeChanged();
void sortOrderChanged();
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
Notifications::SortMode m_sortMode = Notifications::SortByDate;
Qt::SortOrder m_sortOrder = Qt::DescendingOrder;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment