if (_systemIconTheme.isEmpty() || _systemIconTheme == fallbackTheme || s.value("Icons/OverrideSystemTheme", false).toBool()) {
// We have a valid fallback theme and want to override the system theme (if it's even defined), so we're basically done
QIcon::setThemeName(fallbackTheme);
+ emit iconThemeRefreshed();
return;
}
if (!_dummyThemeDir->isValid() || !QDir{_dummyThemeDir->path()}.mkpath("icons/quassel-icon-proxy/apps/32")) {
qWarning() << "Could not create temporary directory for proxying the system icon theme, using fallback";
QIcon::setThemeName(fallbackTheme);
+ emit iconThemeRefreshed();
return;
}
// Add this to XDG_DATA_DIRS, otherwise KIconLoader complains
if (!indexFile.open(QFile::WriteOnly|QFile::Truncate)) {
qWarning() << "Could not create index file for proxying the system icon theme, using fallback";
QIcon::setThemeName(fallbackTheme);
+ emit iconThemeRefreshed();
return;
}
if (indexFile.write(indexContents.toLatin1()) < 0) {
qWarning() << "Could not write index file for proxying the system icon theme, using fallback";
QIcon::setThemeName(fallbackTheme);
+ emit iconThemeRefreshed();
return;
}
indexFile.close();
// Qt4 doesn't support QTemporaryDir. Since it's deprecated and slated to be removed soon anyway, we don't bother
// writing a replacement and simply don't support not overriding the system theme.
QIcon::setThemeName(fallbackTheme);
+ emit iconThemeRefreshed();
#endif
}
*/
void refreshIconTheme();
+signals:
+ void iconThemeRefreshed();
+
protected slots:
void connectedToCore() override;
void disconnectedFromCore() override;
#ifdef HAVE_DBUS
#include <QApplication>
+#include <QDir>
#include <QMenu>
#include <QMouseEvent>
#include <QTextDocument>
+#include "qtui.h"
#include "quassel.h"
#include "statusnotifieritem.h"
#include "statusnotifieritemdbus.h"
}
};
-
#endif /* HAVE_DBUSMENU */
StatusNotifierItem::StatusNotifierItem(QWidget *parent)
- : StatusNotifierItemParent(parent),
- _statusNotifierItemDBus(0),
- _statusNotifierWatcher(0),
- _notificationsClient(0),
- _notificationsClientSupportsMarkup(true),
- _lastNotificationsDBusId(0)
+ : StatusNotifierItemParent(parent)
+#if QT_VERSION >= 0x050000
+ , _iconThemeDir{QDir::tempPath() + QLatin1String{"/quassel-sni-XXXXXX"}}
+#endif
{
+ // Create a temporary directory that holds copies of the tray icons. That way, visualizers can find our icons.
+ // For Qt4 the relevant icons are installed in hicolor already, so nothing to be done.
+#if QT_VERSION >= 0x050000
+ if (_iconThemeDir.isValid()) {
+ _iconThemePath = _iconThemeDir.path();
+ }
+ else {
+ qWarning() << StatusNotifierItem::tr("Could not create temporary directory for themed tray icons: %1").arg(_iconThemeDir.errorString());
+ }
+#endif
+
+ connect(QtUi::instance(), SIGNAL(iconThemeRefreshed()), this, SLOT(refreshIcons()));
}
qDBusRegisterMetaType<DBusImageVector>();
qDBusRegisterMetaType<DBusToolTipStruct>();
+ refreshIcons();
+
_statusNotifierItemDBus = new StatusNotifierItemDBus(this);
connect(this, SIGNAL(toolTipChanged(QString, QString)), _statusNotifierItemDBus, SIGNAL(NewToolTip()));
StatusNotifierItemParent::init();
trayMenu()->installEventFilter(this);
- // use the appdata icon folder for now
- _iconThemePath = Quassel::findDataFilePath("icons");
-
#ifdef HAVE_DBUSMENU
_menuObjectPath = "/MenuBar";
new QuasselDBusMenuExporter(menuObjectPath(), trayMenu(), _statusNotifierItemDBus->dbusConnection()); // will be added as menu child
//unregistered
//qDebug() << "Connection to the StatusNotifierWatcher lost";
delete _statusNotifierWatcher;
- _statusNotifierWatcher = 0;
+ _statusNotifierWatcher = nullptr;
setMode(Legacy);
}
else if (oldOwner.isEmpty()) {
}
+void StatusNotifierItem::refreshIcons()
+{
+#if QT_VERSION >= 0x050000
+ if (!_iconThemePath.isEmpty()) {
+ QDir baseDir{_iconThemePath + "/hicolor"};
+ baseDir.removeRecursively();
+ for (auto &&trayState : { State::Active, State::Passive, State::NeedsAttention }) {
+ const QIcon &icon = SystemTray::stateIcon(trayState);
+ if (!icon.name().isEmpty()) {
+ for (auto &&size : icon.availableSizes()) {
+ auto pixDir = QString{"%1/%2x%3/status"}.arg(baseDir.absolutePath()).arg(size.width()).arg(size.height());
+ QDir{}.mkpath(pixDir);
+ if (!icon.pixmap(size).save(pixDir + "/" + icon.name() + ".png")) {
+ qWarning() << "Could not save tray icon" << icon.name() << "for size" << size;
+ }
+ }
+ }
+ }
+ }
+#endif
+ if (_statusNotifierItemDBus) {
+ emit _statusNotifierItemDBus->NewIcon();
+ emit _statusNotifierItemDBus->NewAttentionIcon();
+ }
+}
+
+
bool StatusNotifierItem::isSystemTrayAvailable() const
{
if (mode() == StatusNotifier)
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef STATUSNOTIFIERITEM_H_
-#define STATUSNOTIFIERITEM_H_
+#pragma once
#ifdef HAVE_DBUS
+#include <QtGlobal>
+
+#if QT_VERSION >= 0x050000
+# include <QTemporaryDir>
+#endif
+
#include "notificationsclient.h"
#include "systemtray.h"
#include "statusnotifierwatcher.h"
public:
explicit StatusNotifierItem(QWidget *parent);
- virtual ~StatusNotifierItem();
+ ~StatusNotifierItem() override;
- virtual bool isSystemTrayAvailable() const;
- virtual bool isVisible() const;
+ bool isSystemTrayAvailable() const override;
+ bool isVisible() const override;
public slots:
- virtual void setState(State state);
- virtual void setVisible(bool visible);
- virtual void showMessage(const QString &title, const QString &message, MessageIcon icon = Information, int msTimeout = 10000, uint notificationId = 0);
- virtual void closeMessage(uint notificationId);
+ void setState(State state) override;
+ void setVisible(bool visible) override;
+ void showMessage(const QString &title, const QString &message, MessageIcon icon = Information, int msTimeout = 10000, uint notificationId = 0) override;
+ void closeMessage(uint notificationId) override;
protected:
- virtual void init();
- virtual void setMode(Mode mode);
+ void init() override;
+ void setMode(Mode mode) override;
QString title() const;
QString iconName() const;
QString iconThemePath() const;
QString menuObjectPath() const;
- virtual bool eventFilter(QObject *watched, QEvent *event);
+ bool eventFilter(QObject *watched, QEvent *event) override;
private slots:
void activated(const QPoint &pos);
void notificationClosed(uint id, uint reason);
void notificationInvoked(uint id, const QString &action);
+ void refreshIcons();
+
private:
void registerToDaemon();
static const int _protocolVersion;
static const QString _statusNotifierWatcherServiceName;
- StatusNotifierItemDBus *_statusNotifierItemDBus;
+ StatusNotifierItemDBus *_statusNotifierItemDBus{nullptr};
- org::kde::StatusNotifierWatcher *_statusNotifierWatcher;
- org::freedesktop::Notifications *_notificationsClient;
- bool _notificationsClientSupportsMarkup;
- bool _notificationsClientSupportsActions;
- quint32 _lastNotificationsDBusId;
+ org::kde::StatusNotifierWatcher *_statusNotifierWatcher{nullptr};
+ org::freedesktop::Notifications *_notificationsClient{nullptr};
+ bool _notificationsClientSupportsMarkup{false};
+ bool _notificationsClientSupportsActions{false};
+ quint32 _lastNotificationsDBusId{0};
QHash<uint, uint> _notificationsIdMap; ///< Maps our own notification ID to the D-Bus one
QString _iconThemePath;
QString _menuObjectPath;
+#if QT_VERSION >= 0x050000
+ QTemporaryDir _iconThemeDir;
+#endif
+
friend class StatusNotifierItemDBus;
};
-
#endif /* HAVE_DBUS */
-#endif /* STATUSNOTIFIERITEM_H_ */