From b8757abecf1defc8ff2912ff0464f54cd0d195cb Mon Sep 17 00:00:00 2001 From: cutefishd Date: Thu, 8 Apr 2021 19:00:09 +0800 Subject: [PATCH] Add app icon to left area --- qml/main.qml | 20 +++++++--- src/activity.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++++-- src/activity.h | 9 +++++ 3 files changed, 119 insertions(+), 9 deletions(-) diff --git a/qml/main.qml b/qml/main.qml index 81725fc..5b16639 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -61,17 +61,25 @@ Item { anchors.rightMargin: Meui.Units.smallSpacing spacing: Meui.Units.largeSpacing + Image { + width: 22 + height: 22 + sourceSize: Qt.size(width, height) + source: "image://icontheme/" + acticity.icon + visible: status === Image.Ready + } + Label { id: acticityLabel text: acticity.title } - Image { - width: 16 - height: 16 - sourceSize: Qt.size(width, height) - source: "qrc:/images/" + (Meui.Theme.darkMode ? "dark/down.svg" : "light/down.svg") - } +// Image { +// width: 16 +// height: 16 +// sourceSize: Qt.size(width, height) +// source: "qrc:/images/" + (Meui.Theme.darkMode ? "dark/down.svg" : "light/down.svg") +// } } } diff --git a/src/activity.cpp b/src/activity.cpp index 3a1497a..947eccd 100644 --- a/src/activity.cpp +++ b/src/activity.cpp @@ -19,7 +19,13 @@ #include "activity.h" +#include +#include #include +#include +#include +#include + #include #include @@ -29,8 +35,8 @@ Activity::Activity(QObject *parent) onActiveWindowChanged(); connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, this, &Activity::onActiveWindowChanged); - connect(KWindowSystem::self(), static_cast(&KWindowSystem::windowChanged), - this, &Activity::onActiveWindowChanged); + // connect(KWindowSystem::self(), static_cast(&KWindowSystem::windowChanged), + // this, &Activity::onActiveWindowChanged); } QString Activity::title() const @@ -38,6 +44,11 @@ QString Activity::title() const return m_title; } +QString Activity::icon() const +{ + return m_icon; +} + void Activity::close() { NETRootInfo(QX11Info::connection(), NET::CloseWindow).closeWindowRequest(KWindowSystem::activeWindow()); @@ -51,15 +62,97 @@ void Activity::onActiveWindowChanged() // Skip... if (info.windowClassClass() == "cutefish-launcher" || - info.windowClassClass() == "cutefish-desktop") { + info.windowClassClass() == "cutefish-desktop" || + info.windowClassClass() == "cutefish-statusbar") { m_title.clear(); + m_icon.clear(); emit titleChanged(); + emit iconChanged(); return; } + m_pid = info.pid(); + m_windowClass = info.windowClassClass().toLower(); + QString title = info.visibleName(); if (title != m_title) { m_title = title; emit titleChanged(); + m_icon.clear(); + emit iconChanged(); } + + matchInfo(); +} + +void Activity::matchInfo() +{ + QString command = commandFromPid(m_pid); + + qDebug() << command; + + // TODO: optimization + QDirIterator it("/usr/share/applications", { "*.desktop" }, + QDir::NoFilter, QDirIterator::Subdirectories); + + while (it.hasNext()) { + const QString &filePath = it.next(); + + QSettings desktop(filePath, QSettings::IniFormat); + desktop.setIniCodec("UTF-8"); + desktop.beginGroup("Desktop Entry"); + + if (desktop.value("NoDisplay").toBool() || + desktop.value("Hidden").toBool()) { + continue; + } + + QString exec = desktop.value("Exec").toString(); + exec.remove(QRegularExpression("%.")); + exec.remove(QRegularExpression("^\"")); + exec = exec.simplified(); + + if (command == exec) { + QString name = desktop.value(QString("Name[%1]").arg(QLocale::system().name())).toString(); + if (name.isEmpty()) + name = desktop.value("Name").toString(); + + m_title = name; + emit titleChanged(); + + m_icon = desktop.value("Icon").toString(); + emit iconChanged(); + + break; + } + } +} + +QString Activity::commandFromPid(quint32 pid) +{ + QFile file(QString("/proc/%1/cmdline").arg(pid)); + + if (file.open(QIODevice::ReadOnly)) { + QByteArray cmd = file.readAll(); + + // ref: https://github.com/KDE/kcoreaddons/blob/230c98aa7e01f9e36a9c2776f3633182e6778002/src/lib/util/kprocesslist_unix.cpp#L137 + if (!cmd.isEmpty()) { + // extract non-truncated name from cmdline + int zeroIndex = cmd.indexOf('\0'); + int processNameStart = cmd.lastIndexOf('/', zeroIndex); + if (processNameStart == -1) { + processNameStart = 0; + } else { + processNameStart++; + } + + QString name = QString::fromLocal8Bit(cmd.mid(processNameStart, zeroIndex - processNameStart)); + + cmd.replace('\0', ' '); + QString command = QString::fromLocal8Bit(cmd).trimmed(); + return name; + } + } + + return QString(); } diff --git a/src/activity.h b/src/activity.h index b8482ac..2eafa28 100644 --- a/src/activity.h +++ b/src/activity.h @@ -26,22 +26,31 @@ class Activity : public QObject { Q_OBJECT Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QString icon READ icon NOTIFY iconChanged) public: explicit Activity(QObject *parent = nullptr); QString title() const; + QString icon() const; Q_INVOKABLE void close(); private slots: void onActiveWindowChanged(); + void matchInfo(); + + QString commandFromPid(quint32 pid); signals: void titleChanged(); + void iconChanged(); private: QString m_title; + QString m_icon; + QString m_windowClass; + quint32 m_pid; }; #endif // ACTIVITY_H