diff --git a/SysTray.cxx b/SysTray.cxx
index 0dbbebb..d3d02e8 100644
--- a/SysTray.cxx
+++ b/SysTray.cxx
@@ -1,256 +1,257 @@
/*
Copyright 2017 Martin Koller, kollix@aon.at
This file is part of liquidshell.
liquidshell 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.
liquidshell 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 liquidshell. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//--------------------------------------------------------------------------------
static const QLatin1String WATCHER_SERVICE("org.kde.StatusNotifierWatcher");
//--------------------------------------------------------------------------------
SysTray::SysTray(DesktopPanel *parent)
: QFrame(parent)
{
qRegisterMetaType("KDbusImageStruct");
qRegisterMetaType("KDbusImageVector");
qDBusRegisterMetaType();
qDBusRegisterMetaType();
qDBusRegisterMetaType();
setFrameShape(QFrame::StyledPanel);
connect(parent, &DesktopPanel::rowsChanged, this, &SysTray::fill);
QHBoxLayout *hbox = new QHBoxLayout(this);
+ hbox->setContentsMargins(QMargins(4, 0, 4, 0));
vbox = new QVBoxLayout;
vbox->setContentsMargins(QMargins());
vbox->setSpacing(4);
QFrame *separator = new QFrame;
separator->setFrameStyle(QFrame::Plain);
separator->setFrameShape(QFrame::VLine);
appsVbox = new QVBoxLayout;
appsVbox->setContentsMargins(QMargins());
appsVbox->setSpacing(4);
hbox->addLayout(vbox);
hbox->addWidget(separator);
hbox->addLayout(appsVbox);
if ( QDBusConnection::sessionBus().isConnected() )
{
serviceName = QString("org.kde.StatusNotifierHost-%1").arg(QApplication::applicationPid());
QDBusConnection::sessionBus().registerService(serviceName);
registerWatcher();
}
fill();
}
//--------------------------------------------------------------------------------
void SysTray::fill()
{
// delete all internal widgets
QLayoutItem *child;
while ( (child = vbox->takeAt(0)) )
{
if ( child->layout() )
{
while ( QLayoutItem *widgetItem = child->layout()->takeAt(0) )
delete widgetItem->widget();
}
delete child;
}
const int MAX_ROWS = qobject_cast(parentWidget())->getRows();
QVector rowsLayout(MAX_ROWS);
for (int i = 0; i < MAX_ROWS; i++)
{
rowsLayout[i] = new QHBoxLayout;
rowsLayout[i]->setContentsMargins(QMargins());
rowsLayout[i]->setSpacing(4);
vbox->addLayout(rowsLayout[i]);
}
if ( MAX_ROWS == 1 )
{
rowsLayout[0]->addWidget(new NotificationServer(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new Network(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new DeviceNotifier(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new Battery(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new Bluetooth(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new PkUpdates(this), 0, Qt::AlignLeft);
}
else if ( MAX_ROWS >= 2 )
{
rowsLayout[0]->addWidget(new NotificationServer(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new DeviceNotifier(this), 0, Qt::AlignLeft);
rowsLayout[0]->addWidget(new Bluetooth(this), 0, Qt::AlignLeft);
rowsLayout[1]->addWidget(new Network(this), 0, Qt::AlignLeft);
rowsLayout[1]->addWidget(new Battery(this), 0, Qt::AlignLeft);
rowsLayout[1]->addWidget(new PkUpdates(this), 0, Qt::AlignLeft);
}
// notifier items
qDeleteAll(appsRows);
appsRows.clear();
appsRows.resize(MAX_ROWS);
for (int i = 0; i < MAX_ROWS; i++)
{
appsRows[i] = new QHBoxLayout;
appsRows[i]->setContentsMargins(QMargins());
appsRows[i]->setSpacing(4);
appsVbox->addLayout(appsRows[i]);
}
for (SysTrayNotifyItem *item : items)
itemInitialized(item);
}
//--------------------------------------------------------------------------------
void SysTray::registerWatcher()
{
QDBusMessage msg =
QDBusMessage::createMethodCall(WATCHER_SERVICE, "/StatusNotifierWatcher",
"org.kde.StatusNotifierWatcher",
"RegisterStatusNotifierHost");
msg << serviceName;
QDBusConnection::sessionBus().send(msg);
// get list of currently existing items
msg = QDBusMessage::createMethodCall(WATCHER_SERVICE, "/StatusNotifierWatcher",
"org.freedesktop.DBus.Properties",
"Get");
msg << "org.kde.StatusNotifierWatcher" << "RegisteredStatusNotifierItems";
QDBusPendingCall call = QDBusConnection::sessionBus().asyncCall(msg);
QDBusPendingCallWatcher *pendingCallWatcher = new QDBusPendingCallWatcher(call, this);
connect(pendingCallWatcher, &QDBusPendingCallWatcher::finished, this,
[this](QDBusPendingCallWatcher *w)
{
w->deleteLater();
QDBusPendingReply reply = *w;
QStringList items = reply.value().variant().toStringList();
for (const QString &item : items)
itemRegistered(item);
}
);
// connect for new items
QDBusConnection::sessionBus().
connect(WATCHER_SERVICE, "/StatusNotifierWatcher",
"org.kde.StatusNotifierWatcher",
"StatusNotifierItemRegistered",
this, SLOT(itemRegistered(QString)));
// connect for removed items
QDBusConnection::sessionBus().
connect(WATCHER_SERVICE, "/StatusNotifierWatcher",
"org.kde.StatusNotifierWatcher",
"StatusNotifierItemUnregistered",
this, SLOT(itemUnregistered(QString)));
}
//--------------------------------------------------------------------------------
void SysTray::itemRegistered(QString item)
{
//qDebug() << "itemRegistered" << item;
int slash = item.indexOf('/');
if ( slash < 1 )
return;
QString service = item.left(slash);
QString path = item.mid(slash);
// create item but insert it into the layout just when it was initialized
// since it might be an invalid item which has no StatusNotifierItem path
// and will delete itself on error
SysTrayNotifyItem *sysItem = new SysTrayNotifyItem(this, service, path);
sysItem->setObjectName(item);
sysItem->setFixedSize(QSize(22, 22));
connect(sysItem, &SysTrayNotifyItem::initialized, this, &SysTray::itemInitialized);
}
//--------------------------------------------------------------------------------
void SysTray::itemInitialized(SysTrayNotifyItem *item)
{
// TODO count only visible items
int lowestCount = 0;
int lowestCountAt = 0;
for (int i = 0; i < appsRows.count(); i++)
{
if ( i == 0 )
lowestCount = appsRows[i]->count();
else if ( appsRows[i]->count() < lowestCount )
{
lowestCount = appsRows[i]->count();
lowestCountAt = i;
}
}
appsRows[lowestCountAt]->addWidget(item, 0, Qt::AlignLeft);
if ( !items.contains(item->objectName()) )
{
items.insert(item->objectName(), item);
disconnect(item, &SysTrayNotifyItem::initialized, this, &SysTray::itemInitialized);
}
}
//--------------------------------------------------------------------------------
void SysTray::itemUnregistered(QString item)
{
//qDebug() << "itemUnregistered" << item;
if ( items.contains(item) )
delete items.take(item);
}
//--------------------------------------------------------------------------------