From 0a49edd036c8f81801f8bf953f19126ee95bddbd Mon Sep 17 00:00:00 2001 From: Ye ShanShan Date: Mon, 25 Nov 2024 15:16:38 +0800 Subject: [PATCH] fix: bubble closed when it's still hovering for notification Add a list to delay remove Bubble when it's timeout. Remove bubble when delayRemoveBubble changed. pms: Bug-283823 --- panels/notification/bubble/bubblemodel.cpp | 36 ++++++++++++++++++- panels/notification/bubble/bubblemodel.h | 11 ++++++ panels/notification/bubble/package/Bubble.qml | 7 ++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/panels/notification/bubble/bubblemodel.cpp b/panels/notification/bubble/bubblemodel.cpp index 1cd55a4a7..eb646897a 100644 --- a/panels/notification/bubble/bubblemodel.cpp +++ b/panels/notification/bubble/bubblemodel.cpp @@ -82,6 +82,8 @@ void BubbleModel::clear() qDeleteAll(m_bubbles); m_bubbles.clear(); endResetModel(); + m_delayBubbles.clear(); + m_delayRemovedBubble = -1; updateLevel(); m_updateTimeTipTimer->stop(); @@ -111,8 +113,8 @@ void BubbleModel::remove(int index) if (m_bubbles.count() >= BubbleMaxCount) { beginInsertRows(QModelIndex(), displayRowCount() - 1, displayRowCount() - 1); endInsertRows(); - updateLevel(); } + updateLevel(); } void BubbleModel::remove(const BubbleItem *bubble) @@ -125,8 +127,16 @@ void BubbleModel::remove(const BubbleItem *bubble) BubbleItem *BubbleModel::removeById(qint64 id) { + if (id == m_delayRemovedBubble) { + // Delayed remove + if (!m_delayBubbles.contains(id)) { + m_delayBubbles.append(id); + } + return nullptr; + } for (const auto &item : m_bubbles) { if (item->id() == id) { + m_delayBubbles.removeAll(id); remove(m_bubbles.indexOf(item)); return item; } @@ -158,6 +168,8 @@ QVariant BubbleModel::data(const QModelIndex &index, int role) const switch (role) { case BubbleModel::AppName: return m_bubbles[row]->appName(); + case BubbleModel::Id: + return m_bubbles[row]->id(); case BubbleModel::Body: return m_bubbles[row]->body(); case BubbleModel::Summary: @@ -190,6 +202,7 @@ QHash BubbleModel::roleNames() const { QHash mapRoleNames; mapRoleNames[BubbleModel::AppName] = "appName"; + mapRoleNames[BubbleModel::Id] = "id"; mapRoleNames[BubbleModel::Body] = "body"; mapRoleNames[BubbleModel::Summary] = "summary"; mapRoleNames[BubbleModel::IconName] = "iconName"; @@ -219,6 +232,27 @@ void BubbleModel::setBubbleCount(int count) BubbleMaxCount = count; } +qint64 BubbleModel::delayRemovedBubble() const +{ + return m_delayRemovedBubble; +} + +void BubbleModel::setDelayRemovedBubble(qint64 newDelayRemovedBubble) +{ + if (m_delayRemovedBubble == newDelayRemovedBubble) + return; + const auto oldDelayRemovedBubble = m_delayRemovedBubble; + if (m_delayBubbles.contains(oldDelayRemovedBubble)) { + // Remove last delayed bubble. + QTimer::singleShot(DelayRemovBubbleTime, this, [this, oldDelayRemovedBubble]() { + removeById(oldDelayRemovedBubble); + }); + } + + m_delayRemovedBubble = newDelayRemovedBubble; + emit delayRemovedBubbleChanged(); +} + int BubbleModel::replaceBubbleIndex(const BubbleItem *bubble) const { if (bubble->replacesId() != NoReplaceId) { diff --git a/panels/notification/bubble/bubblemodel.h b/panels/notification/bubble/bubblemodel.h index 91dc5e0fa..12ebb391f 100644 --- a/panels/notification/bubble/bubblemodel.h +++ b/panels/notification/bubble/bubblemodel.h @@ -16,9 +16,11 @@ class BubbleItem; class BubbleModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(qint64 delayRemovedBubble READ delayRemovedBubble WRITE setDelayRemovedBubble NOTIFY delayRemovedBubbleChanged FINAL) public: enum { AppName = Qt::UserRole + 1, + Id, Body, Summary, IconName, @@ -58,6 +60,12 @@ class BubbleModel : public QAbstractListModel int overlayCount() const; void setBubbleCount(int count); + qint64 delayRemovedBubble() const; + void setDelayRemovedBubble(qint64 newDelayRemovedBubble); + +signals: + void delayRemovedBubbleChanged(); + private: int replaceBubbleIndex(const BubbleItem *bubble) const; void updateLevel(); @@ -70,6 +78,9 @@ class BubbleModel : public QAbstractListModel const int LastBubbleMaxIndex{BubbleMaxCount - 1}; const int OverlayMaxCount{2}; const int NoReplaceId{0}; + QList m_delayBubbles; + qint64 m_delayRemovedBubble{-1}; + const int DelayRemovBubbleTime{1000}; }; } diff --git a/panels/notification/bubble/package/Bubble.qml b/panels/notification/bubble/package/Bubble.qml index b32c745cc..c727d0c9a 100644 --- a/panels/notification/bubble/package/Bubble.qml +++ b/panels/notification/bubble/package/Bubble.qml @@ -11,6 +11,13 @@ import org.deepin.dtk 1.0 as D D.Control { id: control property var bubble + onHoveredChanged: function () { + if (control.hovered) { + Applet.bubbles.delayRemovedBubble = bubble.id + } else { + Applet.bubbles.delayRemovedBubble = -1 + } + } contentItem: Loader { sourceComponent: bubble.level <= 1 ? normalCom : overlayCom