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.
This commit is contained in:
committed by
Aleix Pol Gonzalez
parent
fe63b0c9a7
commit
0906e0c680
@@ -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
|
||||
|
||||
|
||||
165
src/trayicon.cpp
165
src/trayicon.cpp
@@ -5,189 +5,40 @@
|
||||
*/
|
||||
#include "trayicon.h"
|
||||
|
||||
// Modified from mujx/nheko's TrayIcon.
|
||||
|
||||
#include <QApplication>
|
||||
#include <QList>
|
||||
#include <QCoreApplication>
|
||||
#include <QMenu>
|
||||
#include <QTimer>
|
||||
#include <QtDebug>
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include <QtMacExtras>
|
||||
#endif
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
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<QSize> MsgCountComposedIcon::availableSizes(QIcon::Mode mode, QIcon::State state) const
|
||||
{
|
||||
Q_UNUSED(mode)
|
||||
Q_UNUSED(state)
|
||||
QList<QSize> 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<MsgCountComposedIcon *>(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<MsgCountComposedIcon *>(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();
|
||||
}
|
||||
|
||||
@@ -13,32 +13,12 @@
|
||||
#include <QIconEngine>
|
||||
#include <QPainter>
|
||||
#include <QRect>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <KStatusNotifierItem>
|
||||
|
||||
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<QSize> 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
|
||||
|
||||
Reference in New Issue
Block a user