diff --git a/src/calloverlaymodel.cpp b/src/calloverlaymodel.cpp
index a450ac6856b7bfe900f0d5f8292667e1c29b3cb0..b0160ee2ce6d0da076e7c38d74a199bc55da9bad 100644
--- a/src/calloverlaymodel.cpp
+++ b/src/calloverlaymodel.cpp
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2021 by Savoir-faire Linux
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,70 +23,6 @@
 #include <QMouseEvent>
 #include <QQuickWindow>
 
-CallControlListModel::CallControlListModel(QObject* parent)
-    : QAbstractListModel(parent)
-{}
-
-int
-CallControlListModel::rowCount(const QModelIndex& parent) const
-{
-    if (parent.isValid())
-        return 0;
-    return data_.size();
-}
-
-QVariant
-CallControlListModel::data(const QModelIndex& index, int role) const
-{
-    if (!index.isValid())
-        return QVariant();
-
-    using namespace CallControl;
-    auto item = data_.at(index.row());
-
-    switch (role) {
-    case Role::ItemAction:
-        return QVariant::fromValue(item.itemAction);
-    case Role::BadgeCount:
-        return QVariant::fromValue(item.badgeCount);
-    }
-    return QVariant();
-}
-
-QHash<int, QByteArray>
-CallControlListModel::roleNames() const
-{
-    using namespace CallControl;
-    QHash<int, QByteArray> roles;
-    roles[ItemAction] = "ItemAction";
-    roles[BadgeCount] = "BadgeCount";
-    return roles;
-}
-
-void
-CallControlListModel::setBadgeCount(int row, int count)
-{
-    if (row >= rowCount())
-        return;
-    data_[row].badgeCount = count;
-    auto idx = index(row, 0);
-    Q_EMIT dataChanged(idx, idx);
-}
-
-void
-CallControlListModel::addItem(const CallControl::Item& item)
-{
-    beginResetModel();
-    data_.append(item);
-    endResetModel();
-}
-
-void
-CallControlListModel::clearData()
-{
-    data_.clear();
-}
-
 IndexRangeFilterProxyModel::IndexRangeFilterProxyModel(QAbstractListModel* parent)
     : QSortFilterProxyModel(parent)
 {
@@ -188,13 +125,13 @@ PendingConferenceesListModel::connectSignals()
     disconnect(beginRemovePendingConferencesRows_);
     disconnect(endRemovePendingConferencesRows_);
 
+    using namespace PendingConferences;
     callsStatusChanged_ = connect(lrcInstance_->getCurrentCallModel(),
                                   &NewCallModel::callStatusChanged,
-                                  this,
-                                  [this]() {
-                                      dataChanged(index(0, 0),
-                                                  index(rowCount() - 1),
-                                                  {PendingConferences::Role::CallStatus});
+                                  [this](const QString&, int) {
+                                      Q_EMIT dataChanged(index(0, 0),
+                                                         index(rowCount() - 1),
+                                                         {Role::CallStatus});
                                   });
 
     beginInsertPendingConferencesRows_ = connect(
@@ -233,6 +170,77 @@ PendingConferenceesListModel::connectSignals()
     endResetModel();
 }
 
+CallControlListModel::CallControlListModel(QObject* parent)
+    : QAbstractListModel(parent)
+{}
+
+int
+CallControlListModel::rowCount(const QModelIndex& parent) const
+{
+    if (parent.isValid())
+        return 0;
+    return data_.size();
+}
+
+QVariant
+CallControlListModel::data(const QModelIndex& index, int role) const
+{
+    if (!index.isValid())
+        return QVariant();
+
+    using namespace CallControl;
+    auto item = data_.at(index.row());
+
+    switch (role) {
+    case Role::ItemAction:
+        return QVariant::fromValue(item.itemAction);
+    case Role::UrgentCount:
+        return QVariant::fromValue(item.urgentCount);
+    }
+    return QVariant();
+}
+
+QHash<int, QByteArray>
+CallControlListModel::roleNames() const
+{
+    using namespace CallControl;
+    QHash<int, QByteArray> roles;
+    roles[ItemAction] = "ItemAction";
+    roles[UrgentCount] = "UrgentCount";
+    return roles;
+}
+
+void
+CallControlListModel::setUrgentCount(QVariant item, int count)
+{
+    const auto* obj = item.value<QObject*>();
+    auto it = std::find_if(data_.cbegin(), data_.cend(), [obj](const auto& item) {
+        return item.itemAction == obj;
+    });
+    if (it != data_.cend()) {
+        auto row = std::distance(data_.cbegin(), it);
+        if (row >= rowCount())
+            return;
+        data_[row].urgentCount = count;
+        auto idx = index(row, 0);
+        Q_EMIT dataChanged(idx, idx);
+    }
+}
+
+void
+CallControlListModel::addItem(const CallControl::Item& item)
+{
+    beginResetModel();
+    data_.append(item);
+    endResetModel();
+}
+
+void
+CallControlListModel::clearData()
+{
+    data_.clear();
+}
+
 CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
     : QObject(parent)
     , lrcInstance_(instance)
@@ -247,7 +255,7 @@ CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
             &CallOverlayModel::overflowIndexChanged,
             this,
             &CallOverlayModel::setControlRanges);
-    overflowVisibleModel_->setFilterRole(CallControl::Role::BadgeCount);
+    overflowVisibleModel_->setFilterRole(CallControl::Role::UrgentCount);
 }
 
 void
@@ -264,9 +272,9 @@ CallOverlayModel::addSecondaryControl(const QVariant& action)
 }
 
 void
-CallOverlayModel::setBadgeCount(int row, int count)
+CallOverlayModel::setUrgentCount(QVariant row, int count)
 {
-    secondaryModel_->setBadgeCount(row, count);
+    secondaryModel_->setUrgentCount(row, count);
 }
 
 QVariant
diff --git a/src/calloverlaymodel.h b/src/calloverlaymodel.h
index 5aecc90e2a843034e7b500d91da19e0679ccc154..040fbf549570d7a6ea5c56f2811e09f22c7bac3f 100644
--- a/src/calloverlaymodel.h
+++ b/src/calloverlaymodel.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2021 by Savoir-faire Linux
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,13 +36,13 @@
 
 namespace CallControl {
 Q_NAMESPACE
-enum Role { ItemAction = Qt::UserRole + 1, BadgeCount };
+enum Role { ItemAction = Qt::UserRole + 1, UrgentCount };
 Q_ENUM_NS(Role)
 
 struct Item
 {
     QObject* itemAction;
-    int badgeCount {0};
+    int urgentCount {0};
 };
 } // namespace CallControl
 
@@ -56,24 +57,6 @@ enum Role {
 Q_ENUM_NS(Role)
 } // namespace PendingConferences
 
-class CallControlListModel : public QAbstractListModel
-{
-    Q_OBJECT
-public:
-    CallControlListModel(QObject* parent = nullptr);
-
-    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
-    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
-    QHash<int, QByteArray> roleNames() const override;
-
-    void setBadgeCount(int row, int count);
-    void addItem(const CallControl::Item& item);
-    void clearData();
-
-private:
-    QList<CallControl::Item> data_;
-};
-
 class IndexRangeFilterProxyModel : public QSortFilterProxyModel
 {
     Q_OBJECT
@@ -112,6 +95,24 @@ private:
     QMetaObject::Connection endRemovePendingConferencesRows_;
 };
 
+class CallControlListModel : public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    CallControlListModel(QObject* parent = nullptr);
+
+    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
+    QHash<int, QByteArray> roleNames() const override;
+
+    void setUrgentCount(QVariant item, int count);
+    void addItem(const CallControl::Item& item);
+    void clearData();
+
+private:
+    QList<CallControl::Item> data_;
+};
+
 class CallOverlayModel : public QObject
 {
     Q_OBJECT
@@ -122,7 +123,7 @@ public:
 
     Q_INVOKABLE void addPrimaryControl(const QVariant& action);
     Q_INVOKABLE void addSecondaryControl(const QVariant& action);
-    Q_INVOKABLE void setBadgeCount(int row, int count);
+    Q_INVOKABLE void setUrgentCount(QVariant item, int count);
     Q_INVOKABLE void clearControls();
 
     Q_INVOKABLE QVariant primaryModel();
diff --git a/src/mainview/components/CallActionBar.qml b/src/mainview/components/CallActionBar.qml
index 484ef66145e135ee14157745abdc1c045eb55c81..a140ce95eb972e838ff790dd08ca5832dd73cdd1 100644
--- a/src/mainview/components/CallActionBar.qml
+++ b/src/mainview/components/CallActionBar.qml
@@ -210,6 +210,10 @@ Control {
             text: !checked ? JamiStrings.startRec : JamiStrings.stopRec
             property bool blinksWhenChecked: true
             property real size: 28
+            onCheckedChanged: {
+                CallOverlayModel.setUrgentCount(recordAction,
+                                                checked ? -1 : 0)
+            }
         },
         Action {
             id: pluginsAction
@@ -345,9 +349,10 @@ Control {
                                    "#80777777" :
                                    "#80444444"
                     type: {
-                        if ((overflowItemListView.count &&
-                                !urgentOverflowListView.count) ||
-                                overflowHiddenListView.count) {
+                        if (overflowItemListView.count ||
+                                urgentOverflowListView.count ||
+                                (overflowHiddenListView.count &&
+                                overflowButton.popup.visible)) {
                             return HalfPill.None
                         } else {
                             return HalfPill.Left
@@ -370,7 +375,10 @@ Control {
 
                         spacing: itemSpacing
                         anchors.fill: parent
-                        model: CallOverlayModel.overflowVisibleModel()
+                        model: !overflowButton.popup.visible ?
+                                   CallOverlayModel.overflowVisibleModel() :
+                                   null
+
                         delegate: buttonDelegate
                         ScrollIndicator.vertical: ScrollIndicator {}
 
diff --git a/src/mainview/components/CallButtonDelegate.qml b/src/mainview/components/CallButtonDelegate.qml
index 892f635fd2545283a840ab65adcbdd58ee4371f3..0822e4867570174b108f19217ce3e4a4724c46fb 100644
--- a/src/mainview/components/CallButtonDelegate.qml
+++ b/src/mainview/components/CallButtonDelegate.qml
@@ -115,13 +115,15 @@ ItemDelegate {
 
         anchors.centerIn: parent
         horizontalAlignment: Text.AlignHCenter
-        source: ItemAction.icon.source
-        color: ItemAction.icon.color
+        source: ItemAction ? ItemAction.icon.source : ""
+        color: ItemAction ? ItemAction.icon.color : null
 
         SequentialAnimation on opacity {
             loops: Animation.Infinite
-            running: ItemAction.blinksWhenChecked !== undefined &&
+            running: ItemAction !== undefined &&
+                     ItemAction.blinksWhenChecked !== undefined &&
                      ItemAction.blinksWhenChecked && checked
+            onStopped: icon.opacity = 1
             NumberAnimation { from: 1; to: 0; duration: JamiTheme.recordBlinkDuration }
             NumberAnimation { from: 0; to: 1; duration: JamiTheme.recordBlinkDuration }
         }
@@ -142,7 +144,9 @@ ItemDelegate {
             id: toolTip
             parent: parent
             visible: text.length > 0 && (wrapper.hovered || menu.hovered)
-            text: menu.hovered ? menuAction.text : ItemAction.text
+            text: menu.hovered ?
+                      menuAction.text :
+                      (ItemAction !== undefined ? ItemAction.text : null)
             verticalPadding: 1
             font.pointSize: 9
         }
@@ -155,7 +159,7 @@ ItemDelegate {
 
         indicator: null
 
-        visible: menuAction !== undefined && !BadgeCount
+        visible: menuAction !== undefined && !UrgentCount
 
         y: isVertical ? 0 : -4
         x: isVertical ? -4 : 0
@@ -256,6 +260,7 @@ ItemDelegate {
                 property real menuItemWidth: 0
                 property real menuItemHeight: 39
 
+                pixelAligned: true
                 orientation: ListView.Vertical
                 implicitWidth: menuItemWidth
                 implicitHeight: Math.min(contentHeight,
@@ -306,7 +311,8 @@ ItemDelegate {
     BadgeNotifier {
         id: badge
 
-        count: BadgeCount
+        visible: count > 0
+        count: UrgentCount
         anchors.horizontalCenter: parent.horizontalCenter
         width: 18
         height: width