From 0906e0c680838fabf6b75863dcc4bd0d0495a379 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Tue, 24 Nov 2020 03:21:25 +0100 Subject: [PATCH] Fix system tray, clean it up At first I noticed it wasn't working like it should, then realised it was using APIs that are largely unadvised. Also I saw there's some kind of system to render numbers in there but this is also something we generally do not do. There's better ways to display such information (e.g. using the com.canonical.Unity interface), so I wouldn't bother having ad-hoc code in there. And if we need to have it, we better have it in KNotifications. It now will also use the icon from the theme. --- src/controller.cpp | 3 +- src/trayicon.cpp | 165 +++------------------------------------------ src/trayicon.h | 36 +--------- 3 files changed, 11 insertions(+), 193 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 07c73da21..8605242b7 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -61,8 +61,7 @@ Controller::Controller(QObject *parent) #ifndef Q_OS_ANDROID TrayIcon *trayIcon = new TrayIcon(this); connect(trayIcon, &TrayIcon::showWindow, this, &Controller::showWindow); - trayIcon->setVisible(true); - trayIcon->setIconSource(":/assets/img/icon.png"); + trayIcon->setIconSource("neochat"); trayIcon->setIsOnline(true); #endif diff --git a/src/trayicon.cpp b/src/trayicon.cpp index fbc74271d..1384e37d8 100644 --- a/src/trayicon.cpp +++ b/src/trayicon.cpp @@ -5,189 +5,40 @@ */ #include "trayicon.h" -// Modified from mujx/nheko's TrayIcon. - -#include -#include +#include #include -#include -#include - -#if defined(Q_OS_MAC) -#include -#endif #include -MsgCountComposedIcon::MsgCountComposedIcon(const QString &filename) - : QIconEngine() -{ - icon_ = QIcon(filename); -} - -void MsgCountComposedIcon::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) -{ - painter->setRenderHint(QPainter::TextAntialiasing); - painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->setRenderHint(QPainter::Antialiasing); - - icon_.paint(painter, rect, Qt::AlignCenter, mode, state); - - if (isOnline && msgCount <= 0) - return; - - QColor backgroundColor("red"); - QColor textColor("white"); - - QBrush brush; - brush.setStyle(Qt::SolidPattern); - brush.setColor(backgroundColor); - - painter->setBrush(brush); - painter->setPen(Qt::NoPen); - painter->setFont(QFont("Open Sans", 8, QFont::Black)); - - QRectF bubble(rect.width() - BubbleDiameter, rect.height() - BubbleDiameter, BubbleDiameter, BubbleDiameter); - painter->drawEllipse(bubble); - painter->setPen(QPen(textColor)); - painter->setBrush(Qt::NoBrush); - if (!isOnline) { - painter->drawText(bubble, Qt::AlignCenter, "x"); - } else if (msgCount >= 100) { - painter->drawText(bubble, Qt::AlignCenter, "99+"); - } else { - painter->drawText(bubble, Qt::AlignCenter, QString::number(msgCount)); - } -} - -QIconEngine *MsgCountComposedIcon::clone() const -{ - return new MsgCountComposedIcon(*this); -} - -QList MsgCountComposedIcon::availableSizes(QIcon::Mode mode, QIcon::State state) const -{ - Q_UNUSED(mode) - Q_UNUSED(state) - QList sizes; - sizes.append(QSize(24, 24)); - sizes.append(QSize(32, 32)); - sizes.append(QSize(48, 48)); - sizes.append(QSize(64, 64)); - sizes.append(QSize(128, 128)); - sizes.append(QSize(256, 256)); - return sizes; -} - -QPixmap MsgCountComposedIcon::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QImage img(size, QImage::Format_ARGB32); - img.fill(qRgba(0, 0, 0, 0)); - QPixmap result = QPixmap::fromImage(img, Qt::NoFormatConversion); - { - QPainter painter(&result); - paint(&painter, QRect(QPoint(0, 0), size), mode, state); - } - return result; -} - TrayIcon::TrayIcon(QObject *parent) - : QSystemTrayIcon(parent) + : KStatusNotifierItem(parent) { QMenu *menu = new QMenu(); - viewAction_ = new QAction(i18n("Show"), parent); - quitAction_ = new QAction(i18n("Quit"), parent); + auto viewAction_ = new QAction(i18n("Show"), parent); connect(viewAction_, &QAction::triggered, this, &TrayIcon::showWindow); - connect(quitAction_, &QAction::triggered, this, QApplication::quit); - - connect(this, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) { - // Usually left click - if (reason == QSystemTrayIcon::ActivationReason::Trigger) { + connect(this, &KStatusNotifierItem::activateRequested, this, [this] (bool active) { + if (active) { Q_EMIT showWindow(); } }); menu->addAction(viewAction_); - menu->addAction(quitAction_); + setCategory(Communications); setContextMenu(menu); } -void TrayIcon::setNotificationCount(int count) -{ - m_notificationCount = count; -// Use the native badge counter in MacOS. -#if defined(Q_OS_MAC) - auto labelText = count == 0 ? "" : QString::number(count); - - if (labelText == QtMac::badgeLabelText()) - return; - - QtMac::setBadgeLabelText(labelText); -#elif defined(Q_OS_WIN) -// FIXME: Find a way to use Windows apis for the badge counter (if any). -#else - if (!icon_ || count == icon_->msgCount) - return; - - // Custom drawing on Linux. - MsgCountComposedIcon *tmp = static_cast(icon_->clone()); - tmp->msgCount = count; - - setIcon(QIcon(tmp)); - - icon_ = tmp; -#endif - Q_EMIT notificationCountChanged(); -} - void TrayIcon::setIsOnline(bool online) { m_isOnline = online; -#if defined(Q_OS_MAC) - if (online) { - auto labelText = m_notificationCount == 0 ? "" : QString::number(m_notificationCount); - - if (labelText == QtMac::badgeLabelText()) - return; - - QtMac::setBadgeLabelText(labelText); - } else { - auto labelText = "x"; - - if (labelText == QtMac::badgeLabelText()) - return; - - QtMac::setBadgeLabelText(labelText); - } -#elif defined(Q_OS_WIN) -// FIXME: Find a way to use Windows apis for the badge counter (if any). -#else - if (!icon_ || online == icon_->isOnline) - return; - - // Custom drawing on Linux. - MsgCountComposedIcon *tmp = static_cast(icon_->clone()); - tmp->isOnline = online; - - setIcon(QIcon(tmp)); - - icon_ = tmp; -#endif + setStatus(Active); Q_EMIT isOnlineChanged(); } void TrayIcon::setIconSource(const QString &source) { m_iconSource = source; -#if defined(Q_OS_MAC) || defined(Q_OS_WIN) - setIcon(QIcon(source)); -#else - icon_ = new MsgCountComposedIcon(source); - setIcon(QIcon(icon_)); - icon_->isOnline = m_isOnline; - icon_->msgCount = m_notificationCount; -#endif + setIconByName(source); Q_EMIT iconSourceChanged(); } diff --git a/src/trayicon.h b/src/trayicon.h index 2c48b85fc..6a6492c1e 100644 --- a/src/trayicon.h +++ b/src/trayicon.h @@ -13,32 +13,12 @@ #include #include #include -#include +#include -class MsgCountComposedIcon : public QIconEngine -{ -public: - MsgCountComposedIcon(const QString &filename); - - virtual void paint(QPainter *p, const QRect &rect, QIcon::Mode mode, QIcon::State state) override; - virtual QIconEngine *clone() const override; - virtual QList availableSizes(QIcon::Mode mode, QIcon::State state) const override; - virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; - - int msgCount = 0; - bool isOnline = true; // Default to false? - -private: - const int BubbleDiameter = 14; - - QIcon icon_; -}; - -class TrayIcon : public QSystemTrayIcon +class TrayIcon : public KStatusNotifierItem { Q_OBJECT Q_PROPERTY(QString iconSource READ iconSource WRITE setIconSource NOTIFY iconSourceChanged) - Q_PROPERTY(int notificationCount READ notificationCount WRITE setNotificationCount NOTIFY notificationCountChanged) Q_PROPERTY(bool isOnline READ isOnline WRITE setIsOnline NOTIFY isOnlineChanged) public: TrayIcon(QObject *parent = nullptr); @@ -49,12 +29,6 @@ public: } void setIconSource(const QString &source); - int notificationCount() - { - return m_notificationCount; - } - void setNotificationCount(int count); - bool isOnline() { return m_isOnline; @@ -70,13 +44,7 @@ Q_SIGNALS: private: QString m_iconSource; - int m_notificationCount = 0; bool m_isOnline = true; - - QAction *viewAction_; - QAction *quitAction_; - - MsgCountComposedIcon *icon_ = nullptr; }; #endif // TRAYICON_H