diff --git a/overlayButton.cpp b/overlayButton.cpp
deleted file mode 100644
index 94112311cb05306c2f62843e81340b73f58fc8d9..0000000000000000000000000000000000000000
--- a/overlayButton.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/**************************************************************************
-* Copyright (C) 2019 by Savoir-faire Linux                                *
-* Author: Yang Wang <yang.wang@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    *
-* the Free Software Foundation; either version 3 of the License, or       *
-* (at your option) any later version.                                     *
-*                                                                         *
-* This program is distributed in the hope that it will be useful,         *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of          *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
-* GNU General Public License for more details.                            *
-*                                                                         *
-* You should have received a copy of the GNU General Public License       *
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
-**************************************************************************/
-#include "overlaybutton.h"
-
-#include "utils.h"
-
-#include <QEvent>
-
-OverlayButton::OverlayButton(QWidget *parent)
-    : QPushButton(parent)
-{
-    btnCallbacks_.push_back(
-        [this](QEvent* event) {
-            if (event->type() == QEvent::HoverEnter) isHovered_ = true;
-            return true;
-        });
-    btnCallbacks_.push_back(
-        [this](QEvent* event) {
-            if (event->type() == QEvent::HoverLeave) isHovered_ = false;
-            return true;
-        });
-
-    connect(this, SIGNAL(toggled(bool)), this, SLOT(slotOnToggle(bool)));
-}
-
-OverlayButton::~OverlayButton()
-{
-}
-
-void
-OverlayButton::setOriginPix(QPixmap originPixPath)
-{
-    pathOriginal_ = originPixPath;
-}
-
-QPixmap
-OverlayButton::getOriginPix() const
-{
-    return pathOriginal_;
-}
-
-void
-OverlayButton::setCheckedPix(QPixmap checkedPixPath)
-{
-    pathChecked_ = checkedPixPath;
-}
-
-QPixmap
-OverlayButton::getCheckedPix() const
-{
-    return pathChecked_;
-}
-
-void
-OverlayButton::setTintColor(QColor tint_color)
-{
-    tintColor_ = tint_color;
-}
-
-QColor
-OverlayButton::getTintColor() const
-{
-    return tintColor_;
-}
-
-void
-OverlayButton::updateIcon(QEvent* event)
-{
-    if (!event)
-        return;
-    if (event->type() != QEvent::HoverEnter &&
-        event->type() != QEvent::HoverLeave) {
-        return;
-    }
-    setButtonIcon();
-}
-
-void
-OverlayButton::setButtonIcon()
-{
-    if (isSelected_) {
-        if (isHovered_) {
-            setIcon(tintCheckedIc_);
-        } else {
-            setIcon(checkedIc_);
-        }
-    } else {
-        if (isHovered_) {
-            setIcon(tintOriginIc_);
-        } else {
-            setIcon(originIc_);
-        }
-    }
-}
-
-bool
-OverlayButton::event(QEvent* event)
-{
-    QPushButton::event(event);
-
-    if (isFirstTime_) {
-        originIc_ = QPixmap(pathOriginal_);
-        checkedIc_ = QPixmap(pathChecked_);
-        tintOriginIc_ = Utils::generateTintedPixmap(originIc_, tintColor_);
-        tintCheckedIc_ = Utils::generateTintedPixmap(checkedIc_, tintColor_);
-        setIcon(originIc_);
-        isFirstTime_ = false;
-    }
-
-    bool isHandled = false;
-    // iterate the handlers of this class
-    for (auto cb : btnCallbacks_) {
-        isHandled = cb(event);
-    }
-    // emit the signal so that other callback can be defined outside of this class
-    updateIcon(event);
-    emit signalBtnEvent(event);
-
-    return isHandled;
-}
-
-void
-OverlayButton::slotOnToggle(bool checked)
-{
-    isSelected_ = checked;
-    setButtonIcon();
-}
-
-void
-OverlayButton::resetToOriginal()
-{
-    setIcon(originIc_);
-}
-
-void
-OverlayButton::setOverlayButtonChecked(bool checked)
-{
-    Utils::whileBlocking(this)->setChecked(checked);
-    isSelected_ = checked;
-    setButtonIcon();
-}
diff --git a/overlayButton.h b/overlayButton.h
deleted file mode 100644
index a2d51a9bd56212b29a34f236d5d028bf70d1aa64..0000000000000000000000000000000000000000
--- a/overlayButton.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/**************************************************************************
-* Copyright (C) 2019 by Savoir-faire Linux                                *
-* Author: Yang Wang <yang.wang@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    *
-* the Free Software Foundation; either version 3 of the License, or       *
-* (at your option) any later version.                                     *
-*                                                                         *
-* This program is distributed in the hope that it will be useful,         *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of          *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
-* GNU General Public License for more details.                            *
-*                                                                         *
-* You should have received a copy of the GNU General Public License       *
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
-**************************************************************************/
-#pragma once
-
-#include "utils.h"
-
-#include <QColor>
-#include <QImage>
-#include <QPushButton>
-
-#include <functional>
-
-class OverlayButton : public QPushButton {
-    Q_OBJECT;
-
-    Q_PROPERTY(QPixmap originPix READ getOriginPix WRITE setOriginPix DESIGNABLE true NOTIFY originPixChanged);
-    Q_PROPERTY(QPixmap checkedPix READ getCheckedPix WRITE setCheckedPix DESIGNABLE true NOTIFY checkedPixChanged);
-    Q_PROPERTY(QColor tintColor READ getTintColor WRITE setTintColor DESIGNABLE true NOTIFY tintColorChanged);
-
-public:
-    using EventCallback = std::function<bool(QEvent*)>;
-
-    OverlayButton(QWidget*);
-    virtual ~OverlayButton();
-    void resetToOriginal();
-    void setOverlayButtonChecked(bool);
-
-public:
-    void setOriginPix(QPixmap);
-    QPixmap getOriginPix() const;
-    void setCheckedPix(QPixmap);
-    QPixmap getCheckedPix() const;
-    void setTintColor(QColor);
-    QColor getTintColor() const;
-
-signals:
-    void signalBtnEvent(QEvent* event);
-    void originPixChanged(QString);
-    void checkedPixChanged(QString);
-    void tintColorChanged(QColor);
-
-protected:
-    virtual bool event(QEvent* event);
-
-private:
-    void updateIcon(QEvent* event);
-    void setButtonIcon();
-
-private slots:
-    void slotOnToggle(bool);
-
-private:
-    bool isHovered_ = false;
-    bool isSelected_ = false;
-    bool isFirstTime_ = true;
-    QPixmap pathOriginal_;
-    QPixmap pathChecked_;
-    QPixmap originIc_;
-    QPixmap tintOriginIc_;
-    QPixmap checkedIc_;
-    QPixmap tintCheckedIc_;
-    QColor tintColor_;
-    std::vector<EventCallback> btnCallbacks_;
-};
diff --git a/overlaybutton.cpp b/overlaybutton.cpp
index 94112311cb05306c2f62843e81340b73f58fc8d9..3a373779c90bbd464c4a4f89802afb79bd26188f 100644
--- a/overlaybutton.cpp
+++ b/overlaybutton.cpp
@@ -24,52 +24,44 @@
 OverlayButton::OverlayButton(QWidget *parent)
     : QPushButton(parent)
 {
-    btnCallbacks_.push_back(
-        [this](QEvent* event) {
-            if (event->type() == QEvent::HoverEnter) isHovered_ = true;
-            return true;
-        });
-    btnCallbacks_.push_back(
-        [this](QEvent* event) {
-            if (event->type() == QEvent::HoverLeave) isHovered_ = false;
-            return true;
-        });
-
-    connect(this, SIGNAL(toggled(bool)), this, SLOT(slotOnToggle(bool)));
+    connect(this, SIGNAL(toggled(bool)),
+            this, SLOT(slotToggled(bool)));
 }
 
 OverlayButton::~OverlayButton()
-{
-}
+{}
 
 void
 OverlayButton::setOriginPix(QPixmap originPixPath)
 {
-    pathOriginal_ = originPixPath;
+    normalPixmap_ = originPixPath;
+    setIcon(normalPixmap_);
 }
 
 QPixmap
 OverlayButton::getOriginPix() const
 {
-    return pathOriginal_;
+    return normalPixmap_;
 }
 
 void
 OverlayButton::setCheckedPix(QPixmap checkedPixPath)
 {
-    pathChecked_ = checkedPixPath;
+    checkedPixmap_ = checkedPixPath;
 }
 
 QPixmap
 OverlayButton::getCheckedPix() const
 {
-    return pathChecked_;
+    return checkedPixmap_;
 }
 
 void
 OverlayButton::setTintColor(QColor tint_color)
 {
     tintColor_ = tint_color;
+    tintNormalPixmap_ = Utils::generateTintedPixmap(normalPixmap_, tintColor_);
+    tintCheckedPixmap_ = Utils::generateTintedPixmap(checkedPixmap_, tintColor_);
 }
 
 QColor
@@ -79,72 +71,42 @@ OverlayButton::getTintColor() const
 }
 
 void
-OverlayButton::updateIcon(QEvent* event)
+OverlayButton::updateIcon()
 {
-    if (!event)
-        return;
-    if (event->type() != QEvent::HoverEnter &&
-        event->type() != QEvent::HoverLeave) {
-        return;
+    if (isSelected_) {
+        setIcon(isHovered_ ? tintCheckedPixmap_ : checkedPixmap_);
+    } else {
+        setIcon(isHovered_ ? tintNormalPixmap_ : normalPixmap_);
     }
-    setButtonIcon();
 }
 
 void
-OverlayButton::setButtonIcon()
+OverlayButton::enterEvent(QEvent* event)
 {
-    if (isSelected_) {
-        if (isHovered_) {
-            setIcon(tintCheckedIc_);
-        } else {
-            setIcon(checkedIc_);
-        }
-    } else {
-        if (isHovered_) {
-            setIcon(tintOriginIc_);
-        } else {
-            setIcon(originIc_);
-        }
-    }
+    Q_UNUSED(event);
+    isHovered_ = true;
+    updateIcon();
 }
 
-bool
-OverlayButton::event(QEvent* event)
+void
+OverlayButton::leaveEvent(QEvent* event)
 {
-    QPushButton::event(event);
-
-    if (isFirstTime_) {
-        originIc_ = QPixmap(pathOriginal_);
-        checkedIc_ = QPixmap(pathChecked_);
-        tintOriginIc_ = Utils::generateTintedPixmap(originIc_, tintColor_);
-        tintCheckedIc_ = Utils::generateTintedPixmap(checkedIc_, tintColor_);
-        setIcon(originIc_);
-        isFirstTime_ = false;
-    }
-
-    bool isHandled = false;
-    // iterate the handlers of this class
-    for (auto cb : btnCallbacks_) {
-        isHandled = cb(event);
-    }
-    // emit the signal so that other callback can be defined outside of this class
-    updateIcon(event);
-    emit signalBtnEvent(event);
-
-    return isHandled;
+    Q_UNUSED(event);
+    isHovered_ = false;
+    updateIcon();
 }
 
 void
-OverlayButton::slotOnToggle(bool checked)
+OverlayButton::slotToggled(bool checked)
 {
     isSelected_ = checked;
-    setButtonIcon();
+    updateIcon();
 }
 
 void
 OverlayButton::resetToOriginal()
 {
-    setIcon(originIc_);
+    setIcon(normalPixmap_);
 }
 
 void
@@ -152,5 +114,5 @@ OverlayButton::setOverlayButtonChecked(bool checked)
 {
     Utils::whileBlocking(this)->setChecked(checked);
     isSelected_ = checked;
-    setButtonIcon();
+    updateIcon();
 }
diff --git a/overlaybutton.h b/overlaybutton.h
index a2d51a9bd56212b29a34f236d5d028bf70d1aa64..ffd7af841a9df06e798db6b099efb3574faecb01 100644
--- a/overlaybutton.h
+++ b/overlaybutton.h
@@ -17,26 +17,21 @@
 **************************************************************************/
 #pragma once
 
-#include "utils.h"
-
 #include <QColor>
 #include <QImage>
 #include <QPushButton>
 
-#include <functional>
-
 class OverlayButton : public QPushButton {
     Q_OBJECT;
 
-    Q_PROPERTY(QPixmap originPix READ getOriginPix WRITE setOriginPix DESIGNABLE true NOTIFY originPixChanged);
-    Q_PROPERTY(QPixmap checkedPix READ getCheckedPix WRITE setCheckedPix DESIGNABLE true NOTIFY checkedPixChanged);
-    Q_PROPERTY(QColor tintColor READ getTintColor WRITE setTintColor DESIGNABLE true NOTIFY tintColorChanged);
+    Q_PROPERTY(QPixmap originPix READ getOriginPix WRITE setOriginPix DESIGNABLE true);
+    Q_PROPERTY(QPixmap checkedPix READ getCheckedPix WRITE setCheckedPix DESIGNABLE true);
+    Q_PROPERTY(QColor tintColor READ getTintColor WRITE setTintColor DESIGNABLE true);
 
 public:
-    using EventCallback = std::function<bool(QEvent*)>;
+    explicit OverlayButton(QWidget* parent = nullptr);
+    ~OverlayButton();
 
-    OverlayButton(QWidget*);
-    virtual ~OverlayButton();
     void resetToOriginal();
     void setOverlayButtonChecked(bool);
 
@@ -48,32 +43,24 @@ public:
     void setTintColor(QColor);
     QColor getTintColor() const;
 
-signals:
-    void signalBtnEvent(QEvent* event);
-    void originPixChanged(QString);
-    void checkedPixChanged(QString);
-    void tintColorChanged(QColor);
-
 protected:
-    virtual bool event(QEvent* event);
+    void enterEvent(QEvent *event) override;
+    void leaveEvent(QEvent* event) override;
 
 private:
-    void updateIcon(QEvent* event);
-    void setButtonIcon();
+    void updateIcon();
 
 private slots:
-    void slotOnToggle(bool);
+    void slotToggled(bool);
 
 private:
     bool isHovered_ = false;
     bool isSelected_ = false;
-    bool isFirstTime_ = true;
-    QPixmap pathOriginal_;
-    QPixmap pathChecked_;
-    QPixmap originIc_;
-    QPixmap tintOriginIc_;
-    QPixmap checkedIc_;
-    QPixmap tintCheckedIc_;
+
+    QPixmap normalPixmap_;
+    QPixmap checkedPixmap_;
+    QPixmap tintNormalPixmap_;
+    QPixmap tintCheckedPixmap_;
+
     QColor tintColor_;
-    std::vector<EventCallback> btnCallbacks_;
 };
diff --git a/videooverlay.cpp b/videooverlay.cpp
index 2bd73c4d814d60ce40d18c58a57fa9c588425d99..c341b18c978ba23488cdd73d05c3967cb490edc1 100644
--- a/videooverlay.cpp
+++ b/videooverlay.cpp
@@ -109,11 +109,11 @@ VideoOverlay::updateCall(const conversation::Info& convInfo)
     ui->noVideoButton->setVisible(!isAudioOnly);
 
     // Block the signals of buttons
-    Utils::whileBlocking(ui->noMicButton)->setOverlayButtonChecked(isAudioMuted);
-    Utils::whileBlocking(ui->noVideoButton)->setOverlayButtonChecked(isVideoMuted);
-    Utils::whileBlocking(ui->recButton)->setOverlayButtonChecked(isRecording);
-    Utils::whileBlocking(ui->holdButton)->setOverlayButtonChecked(isPaused);
-    Utils::whileBlocking(ui->onHoldLabel)->setVisible(isPaused);
+    ui->noMicButton->setOverlayButtonChecked(isAudioMuted);
+    ui->noVideoButton->setOverlayButtonChecked(isVideoMuted);
+    ui->recButton->setOverlayButtonChecked(isRecording);
+    ui->holdButton->setOverlayButtonChecked(isPaused);
+    ui->onHoldLabel->setVisible(isPaused);
 
     bool isSIP = accInfo.profileInfo.type == lrc::api::profile::Type::SIP;
     ui->addToConferenceButton->setVisible(!isSIP);