1
0
mirror of https://github.com/KDE/latte-dock.git synced 2024-12-25 19:21:41 +03:00

make indicators infrastructure smarter

--indicators are now tracked only based on their
installation path, that means that are updated
more precise when changes are applied and
at the same time views are recreated only when
the show the specific indicator that was changed
This commit is contained in:
Michail Vourlakos 2019-12-31 15:49:53 +02:00
parent c44d5fa5b6
commit 91b345e615
5 changed files with 141 additions and 61 deletions

View File

@ -29,6 +29,7 @@
#include <QMessageBox>
#include <QProcess>
#include <QTemporaryDir>
#include <QTimer>
// KDE
#include <KDirWatch>
@ -49,23 +50,32 @@ Factory::Factory(QObject *parent)
{
m_parentWidget = new QWidget();
m_watchedPaths = Latte::Layouts::Importer::standardPaths();
m_mainPaths = Latte::Layouts::Importer::standardPaths();
for(int i=0; i<m_watchedPaths.count(); ++i) {
m_watchedPaths[i] = m_watchedPaths[i] + "/latte/indicators";
for(int i=0; i<m_mainPaths.count(); ++i) {
m_mainPaths[i] = m_mainPaths[i] + "/latte/indicators";
discoverNewIndicators(m_mainPaths[i]);
}
reload();
//! track paths for changes
for(const auto &dir : m_watchedPaths) {
for(const auto &dir : m_mainPaths) {
KDirWatch::self()->addDir(dir);
}
connect(KDirWatch::self(), &KDirWatch::dirty, this, [ & ](const QString & path) {
if (m_watchedPaths.contains(path)) {
reload();
emit pluginsUpdated();
if (m_indicatorsPaths.contains(path)) {
//! indicator updated
reload(path);
} else if (m_mainPaths.contains(path)){
//! consider indicator addition
discoverNewIndicators(path);
}
});
connect(KDirWatch::self(), &KDirWatch::deleted, this, [ & ](const QString & path) {
if (m_indicatorsPaths.contains(path)) {
//! indicator removed
removeIndicatorRecords(path);
}
});
@ -111,47 +121,46 @@ KPluginMetaData Factory::metadata(QString pluginId)
return KPluginMetaData();
}
void Factory::reload()
void Factory::reload(const QString &indicatorPath)
{
m_plugins.clear();
m_pluginUiPaths.clear();
m_customPluginIds.clear();
m_customPluginNames.clear();
m_customLocalPluginIds.clear();
QString pluginChangedId;
for(const auto &path : m_watchedPaths) {
QDir standard(path);
if (standard.exists()) {
QStringList pluginDirs = standard.entryList(QStringList(),QDir::AllDirs | QDir::NoSymLinks);
for (const auto &pluginDir : pluginDirs) {
if (pluginDir != "." && pluginDir != "..") {
QString metadataFile = standard.absolutePath() + "/" + pluginDir + "/metadata.desktop";
if (!indicatorPath.isEmpty() && indicatorPath != "." && indicatorPath != "..") {
QString metadataFile = indicatorPath + "/metadata.desktop";
if(QFileInfo(metadataFile).exists()) {
KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(metadataFile);
if (metadataAreValid(metadata)) {
QString uiFile = standard.absolutePath() + "/" + pluginDir + "/package/" + metadata.value("X-Latte-MainScript");
pluginChangedId = metadata.pluginId();
QString uiFile = indicatorPath + "/package/" + metadata.value("X-Latte-MainScript");
if (QFileInfo(uiFile).exists() && !m_plugins.contains(metadata.pluginId())) {
if (!m_plugins.contains(metadata.pluginId())) {
m_plugins[metadata.pluginId()] = metadata;
}
if (QFileInfo(uiFile).exists()) {
m_pluginUiPaths[metadata.pluginId()] = QFileInfo(uiFile).absolutePath();
}
if ((metadata.pluginId() != "org.kde.latte.default")
&& (metadata.pluginId() != "org.kde.latte.plasma")) {
if (!m_customPluginIds.contains(metadata.pluginId())) {
m_customPluginIds << metadata.pluginId();
}
if (!m_customPluginNames.contains(metadata.name())) {
m_customPluginNames << metadata.name();
}
if (standard.absolutePath().startsWith(QDir::homePath())) {
m_customLocalPluginIds << metadata.pluginId();
}
m_pluginUiPaths[metadata.pluginId()] = QFileInfo(uiFile).absolutePath();
if (indicatorPath.startsWith(QDir::homePath())) {
m_customLocalPluginIds << metadata.pluginId();
}
}
QString pluginPath = metadata.fileName().remove("metadata.desktop");
qDebug() << " Indicator Package Loaded ::: " << metadata.name() << " [" << metadata.pluginId() << "]" << " - [" <<pluginPath<<"]";
qDebug() << " Indicator Package Loaded ::: " << metadata.name() << " [" << metadata.pluginId() << "]" << " - [" << indicatorPath <<"]";
/*qDebug() << " Indicator value ::: " << metadata.pluginId();
qDebug() << " Indicator value ::: " << metadata.fileName();
@ -160,13 +169,61 @@ void Factory::reload()
qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigXml");*/
}
}
if (!pluginChangedId.isEmpty()) {
emit indicatorChanged(pluginChangedId);
}
}
void Factory::discoverNewIndicators(const QString &main)
{
if (!m_mainPaths.contains(main)) {
return;
}
QDirIterator indicatorsDirs(main, QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags);
while(indicatorsDirs.hasNext()){
indicatorsDirs.next();
QString iPath = indicatorsDirs.filePath();
if (!m_indicatorsPaths.contains(iPath)) {
m_indicatorsPaths << iPath;
KDirWatch::self()->addDir(iPath);
reload(iPath);
}
}
}
emit customPluginsChanged();
void Factory::removeIndicatorRecords(const QString &path)
{
if (m_indicatorsPaths.contains(path)) {
QString pluginId = path.section('/',-1);
m_plugins.remove(pluginId);
m_pluginUiPaths.remove(pluginId);
int pos = m_customPluginIds.indexOf(pluginId);
m_customPluginIds.removeAt(pos);
m_customPluginNames.removeAt(pos);
m_customLocalPluginIds.removeAll(pluginId);
m_indicatorsPaths.removeAll(path);
qDebug() << " indicator removed 1 :: " << pluginId;
KDirWatch::self()->removeDir(path);
//! delay informing the removal in case it is just an update
QTimer::singleShot(1000, [this, pluginId]() {
emit indicatorRemoved(pluginId);
});
}
}
bool Factory::isCustomType(const QString &id) const
{
return ((id != "org.kde.latte.default") && (id != "org.kde.latte.plasma"));
}
bool Factory::metadataAreValid(KPluginMetaData &metadata)

View File

@ -52,6 +52,7 @@ public:
void removeIndicator(QString id);
bool pluginExists(QString id) const;
bool isCustomType(const QString &id) const;
QString uiPath(QString pluginName) const;
@ -63,11 +64,14 @@ public:
//! imports an indicator compressed file
static Latte::Types::ImportExportState importIndicatorFile(QString compressedFile);
signals:
void customPluginsChanged();
void pluginsUpdated();
void indicatorChanged(const QString &indicatorId);
void indicatorRemoved(const QString &indicatorId);
private:
void reload();
void reload(const QString &indicatorPath);
void removeIndicatorRecords(const QString &path);
void discoverNewIndicators(const QString &main);
private:
QHash<QString, KPluginMetaData> m_plugins;
@ -77,7 +81,9 @@ private:
QStringList m_customPluginNames;
QStringList m_customLocalPluginIds;
QStringList m_watchedPaths;
//! plugins paths
QStringList m_mainPaths;
QStringList m_indicatorsPaths;
QWidget *m_parentWidget;
};

View File

@ -54,17 +54,19 @@ Indicator::Indicator(Latte::View *parent)
connect(m_view, &Latte::View::latteTasksArePresentChanged, this, &Indicator::latteTasksArePresentChanged);
connect(m_view, &Latte::View::customPluginsChanged, [this]() {
if (m_corona && !m_corona->indicatorFactory()->pluginExists(m_type)) {
connect(m_view, &Latte::View::indicatorPluginChanged, [this](const QString &indicatorId) {
if (m_corona && m_corona->indicatorFactory()->isCustomType(indicatorId)) {
emit customPluginsChanged();
}
});
connect(m_view, &Latte::View::indicatorPluginRemoved, [this](const QString &indicatorId) {
if (m_corona && m_type == indicatorId && !m_corona->indicatorFactory()->pluginExists(indicatorId)) {
setType("org.kde.latte.default");
}
if (m_corona && m_corona->indicatorFactory()->isCustomType(indicatorId)) {
emit customPluginsChanged();
});
connect(this, &Indicator::pluginChanged, [this]() {
if ((m_type != "org.kde.latte.default") && m_type != "org.kde.latte.plasma") {
setCustomType(m_type);
}
});
@ -266,6 +268,10 @@ void Indicator::load(QString type)
QString path = m_metadata.fileName();
m_pluginPath = path.remove("metadata.desktop");
if (m_corona && m_corona->indicatorFactory()->isCustomType(type)) {
setCustomType(type);
}
updateScheme();
updateComponent();

View File

@ -253,9 +253,19 @@ void View::init()
connect(m_contextMenu, &ViewPart::ContextMenu::menuChanged, this, &View::contextMenuIsShownChanged);
connect(m_corona->indicatorFactory(), &Latte::Indicator::Factory::pluginsUpdated, this, &View::reloadSource);
//! View sends this signal in order to avoid crashes from ViewPart::Indicator when the view is recreated
connect(m_corona->indicatorFactory(), &Latte::Indicator::Factory::customPluginsChanged, this, &View::customPluginsChanged);
connect(m_corona->indicatorFactory(), &Latte::Indicator::Factory::indicatorChanged, this, [&](const QString &indicatorId) {
emit indicatorPluginChanged(indicatorId);
});
connect(this, &View::indicatorPluginChanged, this, [&](const QString &indicatorId) {
if (m_indicator && m_indicator->type() == indicatorId) {
reloadSource();
}
});
connect(m_corona->indicatorFactory(), &Latte::Indicator::Factory::indicatorRemoved, this, &View::indicatorPluginRemoved);
connect(m_corona, &Latte::Corona::availableScreenRectChanged, this, &View::availableScreenRectChangedForViewParts);
///!!!!!

View File

@ -298,7 +298,8 @@ signals:
//! pass on signals to children in order to avoid crashes when View is recreated or destroyed
void availableScreenRectChangedForViewParts();
void customPluginsChanged();
void indicatorPluginChanged(const QString &indicatorId);
void indicatorPluginRemoved(const QString &indicatorId);
//! are used to trigger the Corona relevant signals and in that
//! way we can disable any such signaling all together, e.g. through disconnectSensitiveSignals()