10#include <QCoreApplication>
11#include <QDBusArgument>
12#include <QDBusInterface>
13#include <QDBusConnection>
14#include <QDBusConnectionInterface>
15#include <QDBusMetaType>
27 const auto& img = px.toImage ().convertToFormat (QImage::Format_ARGB32);
30 const auto pixelsCnt = img.width () * img.height ();
31 data.resize (pixelsCnt *
sizeof (quint32));
32 qToBigEndian<quint32> (img.bits (), pixelsCnt, data.data ());
34 return { .Width_ = img.width (), .Height_ = img.height (), .Data_ = data };
42 auto sizes = icon.availableSizes ();
43 constexpr auto fallbackSize = 128;
45 sizes << QSize { fallbackSize, fallbackSize };
52 out.beginStructure ();
68 out.beginStructure ();
100 auto sb = QDBusConnection::sessionBus ();
102 const auto& watchers = sb.interface ()->registeredServiceNames ().value ().filter (
"StatusNotifierWatcher");
103 if (watchers.isEmpty ())
104 throw std::runtime_error {
"no SNI watchers available" };
105 const auto& watcherService = watchers.value (0);
106 QDBusInterface watcher { watcherService,
"/StatusNotifierWatcher", {}, sb };
107 if (!watcher.isValid ())
108 throw std::runtime_error {
"interface to the SNI watcher " + watcherService.toStdString () +
"is invalid" };
110 static int uniqueId = 0;
111 const auto& serviceName = u
"org.freedesktop.StatusNotifierItem-%1-%2"_qsv
112 .arg (QByteArray::number (QCoreApplication::applicationPid ()), QByteArray::number (++uniqueId));
113 if (!sb.registerService (serviceName))
114 throw std::runtime_error {
"unable to register SNI service" };
115 if (!sb.registerObject (
"/StatusNotifierItem",
this))
116 throw std::runtime_error {
"unable to register SNI object" };
118 if (
const auto reply = watcher.call (
"RegisterStatusNotifierItem", serviceName);
119 reply.type () == QDBusMessage::ErrorMessage)
120 throw std::runtime_error {
"unable to register the SNI with the watcher: " + reply.errorMessage ().toStdString () };
146 : QDBusAbstractAdaptor { &impl }
149 qDBusRegisterMetaType<IconFrame> ();
150 qDBusRegisterMetaType<QList<IconFrame>> ();
151 qDBusRegisterMetaType<DBusTooltip> ();
157 menu->popup ({ x, y });
172 emit Impl_.FTI_.
scrolled (delta, orient == u
"Vertical"_qsv ? Qt::Vertical : Qt::Horizontal);
175 QString SNIAdaptor::GetId ()
const
180 QString SNIAdaptor::GetTitle ()
const
185 QString SNIAdaptor::GetStatus ()
const
194 return "NeedsAttention";
197 qWarning () << Q_FUNC_INFO
202 QString SNIAdaptor::GetIconName ()
const
205 [] (
const QString& path) { return path; },
206 [] (
const QIcon&) { return QString {}; });
212 [] (
const QString&) { return QList<IconFrame> {}; },
213 [] (
const QIcon& icon) {
return IconToFrames (icon); });
216 DBusTooltip SNIAdaptor::GetTooltip ()
const
220 .Title_ = Impl_.FTI_.GetInfo ().Title_,
221 .Subtitle_ = Impl_.FTI_.GetTooltip ().HTML_
void UpdateTooltip() override
void UpdateStatus() override
FancyTrayIconFreedesktop(FancyTrayIcon &icon)
void UpdateIcon() override
void UpdateMenu() override
const IconInfo & GetInfo() const
const Icon & GetIcon() const
void scrolled(int, Qt::Orientation)
QMenu * GetContextMenu() const
void secondaryActivated()
void ContextMenu(int x, int y)
void SecondaryActivate(int, int)
void Scroll(int, const QString &)
QList< IconFrame > IconToFrames(const QIcon &icon)
const QDBusArgument & operator>>(const QDBusArgument &in, IconFrame &frame)
QDBusArgument & operator<<(QDBusArgument &out, const IconFrame &frame)
auto Visit(const Either< Left, Right > &either, Args &&... args)
auto Map(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
static IconFrame FromPixmap(const QPixmap &)