diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1576f6d..3bc3240 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,134 +1,146 @@
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
project(liquidshell)
find_package(ECM 1.3.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDECMakeSettings)
include(ECMInstallIcons)
find_package(Qt5 5.6 CONFIG REQUIRED COMPONENTS
Core
Widgets
DBus
X11Extras
)
find_package(KF5 REQUIRED COMPONENTS
WindowSystem WidgetsAddons ConfigWidgets Config KIO IconThemes ItemViews Archive
Notifications I18n NetworkManagerQt Service Solid BluezQt KCMUtils Crash DBusAddons
NewStuff
)
-find_package(packagekitqt5 REQUIRED)
-
set(SOURCES
desktop.cxx
DesktopWidget.cxx
DesktopPanel.cxx
OnScreenVolume.cxx
ConfigureDesktopDialog.cxx
StartMenu.cxx
Launcher.cxx
QuickLaunch.cxx
IconButton.cxx
AppMenu.cxx
Pager.cxx
PagerButton.cxx
WindowList.cxx
ClockWidget.cxx
ClockWidgetConfigureDialog.cxx
TaskBar.cxx
TaskBarButton.cxx
LockLogout.cxx
SysTray.cxx
SysTrayItem.cxx
SysTrayNotifyItem.cxx
DBusTypes.cxx
SysLoad.cxx
NotificationServer.cxx
NotificationList.cxx
Network.cxx
NetworkList.cxx
DeviceNotifier.cxx
DeviceList.cxx
Battery.cxx
Bluetooth.cxx
PopupMenu.cxx
- PkUpdates.cxx
- PkUpdateList.cxx
KdeConnect.cxx
DesktopApplet.cxx
WeatherApplet.cxx
WeatherAppletConfigureDialog.cxx
DiskUsageApplet.cxx
DiskUsageAppletConfigureDialog.cxx
PictureFrameApplet.cxx
PictureFrameAppletConfigureDialog.cxx
)
+find_package(packagekitqt5 QUIET)
+
+if ( packagekitqt5_FOUND )
+ set(SOURCES ${SOURCES}
+ PkUpdates.cxx
+ PkUpdateList.cxx
+ )
+
+ add_definitions(-DWITH_PACKAGEKIT)
+else()
+ message(WARNING "PackageKit integration not available. packagekitqt5 development files not found")
+endif()
+
# e.g. on openSuse Leap 42.3 compile fails as a GLib header included uses signals as var
add_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
ki18n_wrap_ui(UI_FILES
ConfigureDesktopDialog.ui
WeatherAppletConfigureDialog.ui
DiskUsageAppletConfigureDialog.ui
PictureFrameAppletConfigureDialog.ui
)
set(statusnotifieritem_xml ${KNOTIFICATIONS_DBUS_INTERFACES_DIR}/kf5_org.kde.StatusNotifierItem.xml)
set_source_files_properties(${statusnotifieritem_xml} PROPERTIES
INCLUDE "DBusTypes.hxx"
CLASSNAME OrgKdeStatusNotifierItem
)
qt5_add_dbus_interface(SOURCES ${statusnotifieritem_xml} statusnotifieritem_interface)
qt5_add_dbus_adaptor(SOURCES org.freedesktop.Notifications.xml NotificationServer.hxx NotificationServer)
set(TARGET liquidshell)
add_executable(${TARGET} ${SOURCES} ${UI_FILES})
set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 11)
target_link_libraries(${TARGET}
Qt5::Core
Qt5::Widgets
Qt5::DBus
Qt5::X11Extras
KF5::WindowSystem
KF5::WidgetsAddons
KF5::ConfigWidgets
KF5::ConfigCore
KF5::KIOCore
KF5::KIOWidgets
KF5::IconThemes
KF5::Notifications
KF5::I18n
KF5::NetworkManagerQt
KF5::Service
KF5::Solid
KF5::BluezQt
KF5::KCMUtils
KF5::Crash
KF5::DBusAddons
KF5::ItemViews
KF5::Archive
KF5::NewStuff
- PK::packagekitqt5
)
+if ( packagekitqt5_FOUND )
+ target_link_libraries(${TARGET} PK::packagekitqt5)
+endif()
+
install(TARGETS ${TARGET} ${INSTALL_TARGETS_DEFAULT_ARGS})
install(PROGRAMS org.kde.${TARGET}.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES liquidshell.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
ecm_install_icons(ICONS
48-apps-liquidshell.png
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor)
diff --git a/SysTray.cxx b/SysTray.cxx
index d3d02e8..63dd9b2 100644
--- a/SysTray.cxx
+++ b/SysTray.cxx
@@ -1,257 +1,264 @@
/*
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
+
+#ifdef WITH_PACKAGEKIT
#include
+#endif
#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);
+#ifdef WITH_PACKAGEKIT
rowsLayout[0]->addWidget(new PkUpdates(this), 0, Qt::AlignLeft);
+#endif
}
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);
+#ifdef WITH_PACKAGEKIT
rowsLayout[1]->addWidget(new PkUpdates(this), 0, Qt::AlignLeft);
+#endif
}
// 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);
}
//--------------------------------------------------------------------------------