more unfinished changes, process tab for dashboard

This commit is contained in:
2026-09-30 14:26:50 +02:00
parent 0bfda04e91
commit 359f832609
98 changed files with 8633 additions and 2983 deletions
+259
View File
@@ -0,0 +1,259 @@
#pragma once
#include "tickingservice.hpp"
#include <optional>
#include <qabstractitemmodel.h>
#include <qhash.h>
#include <qobject.h>
#include <qqmlintegration.h>
#include <qtmetamacros.h>
#include <qtypes.h>
#include <sys/types.h>
template <typename T> class QFutureWatcher;
namespace ZShell::services {
class ProcessModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum Roles : quint16 {
PidRole = Qt::UserRole + 1,
PpidRole,
CommandRole,
CommandLineRole,
StateRole,
SleepingRole,
CpuUsageRole,
MemoryUsageRole,
ElapsedRole,
UidRole,
UserRole,
IoReadBytesRole,
IoWriteBytesRole,
IconNameRole,
};
Q_ENUM(Roles)
explicit ProcessModel(QObject* parent = nullptr);
[[nodiscard]] int rowCount(
const QModelIndex& parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(
const QModelIndex& index, int role) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] int count() const;
void refresh();
bool killProcess(qint64 pid, int signal = 15) const;
void setDesktopEntryIcons(
QHash<QString, QString> execPathToIcon,
QHash<QString, QString> execNameToIcon);
[[nodiscard]] QString searchText() const;
void setSearchText(const QString& text);
[[nodiscard]] bool currentUserOnly() const;
void setCurrentUserOnly(bool enabled);
[[nodiscard]] int sortField() const;
void setSortField(int field);
[[nodiscard]] bool sortAscending() const;
void setSortAscending(bool ascending);
signals:
void countChanged();
void searchTextChanged();
void currentUserOnlyChanged();
void sortFieldChanged();
void sortAscendingChanged();
private:
struct RawStat {
pid_t pid = 0;
pid_t ppid = 0;
QString comm;
char state = '?';
quint64 utime = 0;
quint64 stime = 0;
quint64 starttime = 0;
};
struct ProcessEntry {
pid_t pid = 0;
pid_t ppid = 0;
QString command;
QString commandLine;
char state = '?';
double cpuPercent = 0.0;
quint64 rssKb = 0;
double elapsedSecs = 0.0;
uid_t uid = 0;
QString username;
QString iconName;
quint64 ioReadBytes = 0;
quint64 ioWriteBytes = 0;
int searchScore = -1;
quint64 lastUtime = 0;
quint64 lastStime = 0;
quint64 starttime = 0;
};
struct StatusInfo {
quint64 rssKb = 0;
uid_t uid = 0;
};
struct IoInfo {
quint64 readBytes = 0;
quint64 writeBytes = 0;
};
struct ScanResult {
QVector<ProcessEntry> entries;
QHash<uid_t, QString> newUidNames;
quint64 iconVersion = 0;
};
static std::optional<RawStat> readStat(pid_t pid);
static QString readCommandLine(pid_t pid, const QString& fallbackComm);
static StatusInfo readStatus(pid_t pid);
static IoInfo readIo(pid_t pid);
static std::optional<double> readUptimeSeconds();
static QString resolveUsername(uid_t uid, QHash<uid_t, QString>& cache);
static QString resolveProcessExe(pid_t pid);
static ScanResult scanProcesses(
double uptime,
double deltaSecs,
QHash<pid_t, int> prevPidToAll,
QVector<ProcessEntry> prevAll,
QHash<uid_t, QString> uidCache,
long clockTicksPerSec,
QHash<QString, QString> execPathToIcon,
QHash<QString, QString> execNameToIcon,
QStringList pathDirs,
bool desktopEntryIconsChanged,
quint64 iconVersion);
void doRefresh();
void onScanFinished();
void applyView();
void converge(const QVector<ProcessEntry>& desired);
[[nodiscard]] int compareEntries(
const ProcessEntry& a, const ProcessEntry& b) const;
[[nodiscard]] static bool isSleeping(const ProcessEntry& e);
QVector<ProcessEntry> mAll;
QHash<pid_t, int> mPidToAll;
QVector<ProcessEntry> mProcesses;
QHash<uid_t, QString> mUidToName;
double mLastUptimeSecs = -1.0;
long mClockTicksPerSec = 100;
QFutureWatcher<ScanResult>* mWatcher = nullptr;
bool mRefreshPending = false;
double mPendingUptime = -1.0;
QString m_searchText;
bool m_currentUserOnly = true;
uid_t m_currentUid = 0;
int m_sortField = 0;
bool m_sortAscending = true;
QHash<QString, QString> mExecPathToIcon;
QHash<QString, QString> mExecNameToIcon;
quint64 m_iconVersion = 0;
quint64 m_scannedIconVersion = 0;
};
class Processes : public TickingService {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
enum SortField : int {
Unsorted = 0,
Pid,
Ppid,
Command,
CommandLine,
State,
Sleeping,
CpuUsage,
MemoryUsage,
Elapsed,
Uid,
User,
IoReadBytes,
IoWriteBytes
};
Q_ENUM(SortField)
private:
Q_PROPERTY(QAbstractItemModel* list READ list CONSTANT)
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(
SortField sortField READ sortField WRITE setSortField NOTIFY
sortFieldChanged)
Q_PROPERTY(
bool sortAscending READ sortAscending WRITE setSortAscending NOTIFY
sortAscendingChanged)
Q_PROPERTY(
QString searchText READ searchText WRITE setSearchText NOTIFY
searchTextChanged)
Q_PROPERTY(
bool currentUserOnly READ currentUserOnly WRITE setCurrentUserOnly
NOTIFY currentUserOnlyChanged)
public:
explicit Processes(QObject* parent = nullptr);
[[nodiscard]] QAbstractItemModel* list() const;
[[nodiscard]] int count() const;
[[nodiscard]] SortField sortField() const;
void setSortField(SortField field);
[[nodiscard]] bool sortAscending() const;
void setSortAscending(bool ascending);
[[nodiscard]] QString searchText() const;
void setSearchText(const QString& text);
[[nodiscard]] bool currentUserOnly() const;
void setCurrentUserOnly(bool enabled);
Q_INVOKABLE void sortBy(SortField field);
Q_INVOKABLE void refresh();
Q_INVOKABLE bool killProcess(qint64 pid, int signal = 15) const;
Q_INVOKABLE void setDesktopEntries(const QVariantList& entries);
signals:
void countChanged();
void sortFieldChanged();
void sortAscendingChanged();
void searchTextChanged();
void currentUserOnlyChanged();
protected:
void tick() override;
private:
ProcessModel* m_model;
};
} // namespace ZShell::services