tidy&format(all): all files formatted and relevant warnings resolved
C++ / build (pull_request) Failing after 15s
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 28s
Python / lint-format (pull_request) Successful in 45s
Python / test (pull_request) Successful in 38s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m45s

This commit is contained in:
2026-06-30 02:04:24 +02:00
parent fed9372b35
commit 467e44bb9f
85 changed files with 4139 additions and 3738 deletions
+64 -34
View File
@@ -23,20 +23,33 @@ PipeWireWorker::PipeWireWorker(std::stop_token token, AudioCollector* collector)
m_loop = pw_main_loop_new(nullptr);
if (!m_loop) {
qWarning() << "PipeWireWorker::init: failed to create PipeWire main loop";
qWarning()
<< "PipeWireWorker::init: failed to create PipeWire main loop";
pw_deinit();
return;
}
timespec timeout = { 0, 10 * SPA_NSEC_PER_MSEC };
m_timer = pw_loop_add_timer(pw_main_loop_get_loop(m_loop), handleTimeout, this);
pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false);
timespec timeout = {0, 10 * SPA_NSEC_PER_MSEC};
m_timer =
pw_loop_add_timer(pw_main_loop_get_loop(m_loop), handleTimeout, this);
pw_loop_update_timer(
pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false);
auto props = pw_properties_new(
PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_MEDIA_CATEGORY, "Capture", PW_KEY_MEDIA_ROLE, "Music", nullptr);
PW_KEY_MEDIA_TYPE,
"Audio",
PW_KEY_MEDIA_CATEGORY,
"Capture",
PW_KEY_MEDIA_ROLE,
"Music",
nullptr);
pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true");
pw_properties_setf(
props, PW_KEY_NODE_LATENCY, "%u/%u", nextPowerOf2(512 * ac::SAMPLE_RATE / 48000), ac::SAMPLE_RATE);
props,
PW_KEY_NODE_LATENCY,
"%u/%u",
nextPowerOf2(512 * ac::SAMPLE_RATE / 48000),
ac::SAMPLE_RATE);
pw_properties_set(props, PW_KEY_NODE_PASSIVE, "true");
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
pw_properties_set(props, PW_KEY_STREAM_DONT_REMIX, "false");
@@ -55,21 +68,28 @@ PipeWireWorker::PipeWireWorker(std::stop_token token, AudioCollector* collector)
params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info);
pw_stream_events events{};
events.state_changed = [](void* data, pw_stream_state, pw_stream_state state, const char*) {
auto* self = static_cast<PipeWireWorker*>(data);
self->streamStateChanged(state);
};
events.state_changed =
[](void* data, pw_stream_state, pw_stream_state state, const char*) {
auto* self = static_cast<PipeWireWorker*>(data);
self->streamStateChanged(state);
};
events.process = [](void* data) {
auto* self = static_cast<PipeWireWorker*>(data);
self->processStream();
};
auto* self = static_cast<PipeWireWorker*>(data);
self->processStream();
};
m_stream = pw_stream_new_simple(pw_main_loop_get_loop(m_loop), "ZShell-shell", props, &events, this);
m_stream = pw_stream_new_simple(
pw_main_loop_get_loop(m_loop), "ZShell-shell", props, &events, this);
const int success = pw_stream_connect(m_stream, PW_DIRECTION_INPUT, PW_ID_ANY,
static_cast<pw_stream_flags>(
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS),
params, 1);
const int success = pw_stream_connect(
m_stream,
PW_DIRECTION_INPUT,
PW_ID_ANY,
static_cast<pw_stream_flags>(
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS |
PW_STREAM_FLAG_RT_PROCESS),
params,
1);
if (success < 0) {
qWarning() << "PipeWireWorker::init: failed to connect stream";
pw_stream_destroy(m_stream);
@@ -98,8 +118,13 @@ void PipeWireWorker::handleTimeout(void* data, uint64_t expirations) {
self->m_collector->clearBuffer();
} else {
self->m_idle = true;
timespec timeout = { 0, 500 * SPA_NSEC_PER_MSEC };
pw_loop_update_timer(pw_main_loop_get_loop(self->m_loop), self->m_timer, &timeout, &timeout, false);
timespec timeout = {0, 500 * SPA_NSEC_PER_MSEC};
pw_loop_update_timer(
pw_main_loop_get_loop(self->m_loop),
self->m_timer,
&timeout,
&timeout,
false);
}
}
}
@@ -108,12 +133,14 @@ void PipeWireWorker::streamStateChanged(pw_stream_state state) {
m_idle = false;
switch (state) {
case PW_STREAM_STATE_PAUSED: {
timespec timeout = { 0, 10 * SPA_NSEC_PER_MSEC };
pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false);
timespec timeout = {0, 10 * SPA_NSEC_PER_MSEC};
pw_loop_update_timer(
pw_main_loop_get_loop(m_loop), m_timer, &timeout, &timeout, false);
break;
}
case PW_STREAM_STATE_STREAMING:
pw_loop_update_timer(pw_main_loop_get_loop(m_loop), m_timer, nullptr, nullptr, false);
pw_loop_update_timer(
pw_main_loop_get_loop(m_loop), m_timer, nullptr, nullptr, false);
break;
case PW_STREAM_STATE_ERROR:
pw_main_loop_quit(m_loop);
@@ -171,7 +198,8 @@ void AudioCollector::clearBuffer() {
auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed);
std::fill(writeBuffer->begin(), writeBuffer->end(), 0.0f);
auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel);
auto* oldRead =
m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel);
m_writeBuffer.store(oldRead, std::memory_order_release);
}
@@ -181,11 +209,13 @@ void AudioCollector::loadChunk(const qint16* samples, quint32 count) {
}
auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed);
std::transform(samples, samples + count, writeBuffer->begin(), [](qint16 sample) {
std::transform(
samples, samples + count, writeBuffer->begin(), [](qint16 sample) {
return sample / 32768.0f;
});
auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel);
auto* oldRead =
m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel);
m_writeBuffer.store(oldRead, std::memory_order_release);
}
@@ -206,9 +236,11 @@ quint32 AudioCollector::readChunk(double* out, quint32 count) {
}
auto* readBuffer = m_readBuffer.load(std::memory_order_acquire);
std::transform(readBuffer->begin(), readBuffer->begin() + count, out, [](float sample) {
return static_cast<double>(sample);
});
std::transform(
readBuffer->begin(),
readBuffer->begin() + count,
out,
[](float sample) { return static_cast<double>(sample); });
return count;
}
@@ -218,8 +250,7 @@ AudioCollector::AudioCollector(QObject* parent)
, m_buffer1(ac::CHUNK_SIZE)
, m_buffer2(ac::CHUNK_SIZE)
, m_readBuffer(&m_buffer1)
, m_writeBuffer(&m_buffer2) {
}
, m_writeBuffer(&m_buffer2) {}
AudioCollector::~AudioCollector() {
stop();
@@ -232,9 +263,8 @@ void AudioCollector::start() {
clearBuffer();
m_thread = std::jthread([this](std::stop_token token) {
PipeWireWorker worker(token, this);
});
m_thread = std::jthread(
[this](std::stop_token token) { PipeWireWorker worker(token, this); });
}
void AudioCollector::stop() {
+35 -35
View File
@@ -22,55 +22,55 @@ constexpr quint32 CHUNK_SIZE = 512;
class AudioCollector;
class PipeWireWorker {
public:
explicit PipeWireWorker(std::stop_token token, AudioCollector* collector);
public:
explicit PipeWireWorker(std::stop_token token, AudioCollector* collector);
void run();
void run();
private:
pw_main_loop* m_loop;
pw_stream* m_stream;
spa_source* m_timer;
bool m_idle;
private:
pw_main_loop* m_loop;
pw_stream* m_stream;
spa_source* m_timer;
bool m_idle;
std::stop_token m_token;
AudioCollector* m_collector;
std::stop_token m_token;
AudioCollector* m_collector;
static void handleTimeout(void* data, uint64_t expirations);
void streamStateChanged(pw_stream_state state);
void processStream();
static void handleTimeout(void* data, uint64_t expirations);
void streamStateChanged(pw_stream_state state);
void processStream();
[[nodiscard]] unsigned int nextPowerOf2(unsigned int n);
[[nodiscard]] unsigned int nextPowerOf2(unsigned int n);
};
class AudioCollector : public Service {
Q_OBJECT
Q_OBJECT
public:
AudioCollector(const AudioCollector&) = delete;
AudioCollector& operator=(const AudioCollector&) = delete;
public:
AudioCollector(const AudioCollector&) = delete;
AudioCollector& operator=(const AudioCollector&) = delete;
static AudioCollector& instance();
static AudioCollector& instance();
void clearBuffer();
void loadChunk(const qint16* samples, quint32 count);
quint32 readChunk(float* out, quint32 count = 0);
quint32 readChunk(double* out, quint32 count = 0);
void clearBuffer();
void loadChunk(const qint16* samples, quint32 count);
quint32 readChunk(float* out, quint32 count = 0);
quint32 readChunk(double* out, quint32 count = 0);
private:
explicit AudioCollector(QObject* parent = nullptr);
~AudioCollector() override;
private:
explicit AudioCollector(QObject* parent = nullptr);
~AudioCollector() override;
std::jthread m_thread;
std::vector<float> m_buffer1;
std::vector<float> m_buffer2;
std::atomic<std::vector<float>*> m_readBuffer;
std::atomic<std::vector<float>*> m_writeBuffer;
quint32 m_sampleCount;
std::jthread m_thread;
std::vector<float> m_buffer1;
std::vector<float> m_buffer2;
std::atomic<std::vector<float>*> m_readBuffer;
std::atomic<std::vector<float>*> m_writeBuffer;
quint32 m_sampleCount;
void reload();
void start() override;
void stop() override;
void reload();
void start() override;
void stop() override;
};
} // namespace ZShell::services
+18 -12
View File
@@ -7,9 +7,7 @@
namespace ZShell::services {
AudioProcessor::AudioProcessor(QObject* parent)
: QObject(parent) {
}
AudioProcessor::AudioProcessor(QObject* parent) : QObject(parent) {}
AudioProcessor::~AudioProcessor() {
stop();
@@ -17,12 +15,17 @@ AudioProcessor::~AudioProcessor() {
void AudioProcessor::init() {
m_timer = new QTimer(this);
m_timer->setInterval(static_cast<int>(ac::CHUNK_SIZE * 1000.0 / ac::SAMPLE_RATE));
m_timer->setInterval(
static_cast<int>(ac::CHUNK_SIZE * 1000.0 / ac::SAMPLE_RATE));
connect(m_timer, &QTimer::timeout, this, &AudioProcessor::process);
}
void AudioProcessor::start() {
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::ref, Qt::QueuedConnection, this);
QMetaObject::invokeMethod(
&AudioCollector::instance(),
&AudioCollector::ref,
Qt::QueuedConnection,
this);
if (m_timer) {
m_timer->start();
}
@@ -32,14 +35,15 @@ void AudioProcessor::stop() {
if (m_timer) {
m_timer->stop();
}
QMetaObject::invokeMethod(&AudioCollector::instance(), &AudioCollector::unref, Qt::QueuedConnection, this);
QMetaObject::invokeMethod(
&AudioCollector::instance(),
&AudioCollector::unref,
Qt::QueuedConnection,
this);
}
AudioProvider::AudioProvider(QObject* parent)
: Service(parent)
, m_processor(nullptr)
, m_thread(nullptr) {
}
: Service(parent), m_processor(nullptr), m_thread(nullptr) {}
AudioProvider::~AudioProvider() {
if (m_thread) {
@@ -50,7 +54,8 @@ AudioProvider::~AudioProvider() {
void AudioProvider::init() {
if (!m_processor) {
qWarning() << "AudioProvider::init: attempted to init with no processor set";
qWarning()
<< "AudioProvider::init: attempted to init with no processor set";
return;
}
@@ -58,7 +63,8 @@ void AudioProvider::init() {
m_processor->moveToThread(m_thread);
connect(m_thread, &QThread::started, m_processor, &AudioProcessor::init);
connect(m_thread, &QThread::finished, m_processor, &AudioProcessor::deleteLater);
connect(
m_thread, &QThread::finished, m_processor, &AudioProcessor::deleteLater);
connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
m_thread->start();
+22 -22
View File
@@ -7,41 +7,41 @@
namespace ZShell::services {
class AudioProcessor : public QObject {
Q_OBJECT
Q_OBJECT
public:
explicit AudioProcessor(QObject* parent = nullptr);
~AudioProcessor() override;
public:
explicit AudioProcessor(QObject* parent = nullptr);
~AudioProcessor() override;
void init();
void init();
void start();
void stop();
void start();
void stop();
protected:
virtual void process() = 0;
protected:
virtual void process() = 0;
private:
QTimer* m_timer;
private:
QTimer* m_timer;
};
class AudioProvider : public Service {
Q_OBJECT
Q_OBJECT
public:
explicit AudioProvider(QObject* parent = nullptr);
~AudioProvider() override;
public:
explicit AudioProvider(QObject* parent = nullptr);
~AudioProvider() override;
protected:
AudioProcessor* m_processor;
protected:
AudioProcessor* m_processor;
void init();
void init();
private:
QThread* m_thread;
private:
QThread* m_thread;
void start() override;
void stop() override;
void start() override;
void stop() override;
};
} // namespace ZShell::services
+7 -6
View File
@@ -10,8 +10,7 @@ BeatProcessor::BeatProcessor(QObject* parent)
: AudioProcessor(parent)
, m_tempo(new_aubio_tempo("default", 1024, ac::CHUNK_SIZE, ac::SAMPLE_RATE))
, m_in(new_fvec(ac::CHUNK_SIZE))
, m_out(new_fvec(2)) {
};
, m_out(new_fvec(2)) {};
BeatProcessor::~BeatProcessor() {
if (m_tempo) {
@@ -36,13 +35,15 @@ void BeatProcessor::process() {
}
}
BeatTracker::BeatTracker(QObject* parent)
: AudioProvider(parent)
, m_bpm(120) {
BeatTracker::BeatTracker(QObject* parent) : AudioProvider(parent), m_bpm(120) {
m_processor = new BeatProcessor();
init();
connect(static_cast<BeatProcessor*>(m_processor), &BeatProcessor::beat, this, &BeatTracker::updateBpm);
connect(
static_cast<BeatProcessor*>(m_processor),
&BeatProcessor::beat,
this,
&BeatTracker::updateBpm);
}
smpl_t BeatTracker::bpm() const {
+24 -24
View File
@@ -7,43 +7,43 @@
namespace ZShell::services {
class BeatProcessor : public AudioProcessor {
Q_OBJECT
Q_OBJECT
public:
explicit BeatProcessor(QObject* parent = nullptr);
~BeatProcessor() override;
public:
explicit BeatProcessor(QObject* parent = nullptr);
~BeatProcessor() override;
signals:
void beat(smpl_t bpm);
signals:
void beat(smpl_t bpm);
protected:
void process() override;
protected:
void process() override;
private:
aubio_tempo_t* m_tempo;
fvec_t* m_in;
fvec_t* m_out;
private:
aubio_tempo_t* m_tempo;
fvec_t* m_in;
fvec_t* m_out;
};
class BeatTracker : public AudioProvider {
Q_OBJECT
QML_ELEMENT
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(smpl_t bpm READ bpm NOTIFY bpmChanged)
Q_PROPERTY(smpl_t bpm READ bpm NOTIFY bpmChanged)
public:
explicit BeatTracker(QObject* parent = nullptr);
public:
explicit BeatTracker(QObject* parent = nullptr);
[[nodiscard]] smpl_t bpm() const;
[[nodiscard]] smpl_t bpm() const;
signals:
void bpmChanged();
void beat(smpl_t bpm);
signals:
void bpmChanged();
void beat(smpl_t bpm);
private:
smpl_t m_bpm;
private:
smpl_t m_bpm;
void updateBpm(smpl_t bpm);
void updateBpm(smpl_t bpm);
};
} // namespace ZShell::services
+18 -12
View File
@@ -2,7 +2,6 @@
#include "audiocollector.hpp"
#include "audioprovider.hpp"
#include <algorithm>
#include <cava/cavacore.h>
#include <cstddef>
#include <qdebug.h>
@@ -14,8 +13,7 @@ CavaProcessor::CavaProcessor(QObject* parent)
, m_plan(nullptr)
, m_in(new double[ac::CHUNK_SIZE])
, m_out(nullptr)
, m_bars(0) {
};
, m_bars(0) {};
CavaProcessor::~CavaProcessor() {
cleanup();
@@ -27,7 +25,8 @@ void CavaProcessor::process() {
return;
}
const int count = static_cast<int>(AudioCollector::instance().readChunk(m_in));
const int count =
static_cast<int>(AudioCollector::instance().readChunk(m_in));
// Process in data via cava
cava_execute(m_in, count, m_out, m_plan);
@@ -35,7 +34,7 @@ void CavaProcessor::process() {
// Apply monstercat filter
QVector<double> values(m_bars);
for(int i = 0; i < m_bars; ++i) {
for (int i = 0; i < m_bars; ++i) {
values[i] = m_out[i];
}
@@ -63,7 +62,8 @@ void CavaProcessor::process() {
void CavaProcessor::setBars(int bars) {
if (bars < 0) {
qWarning() << "CavaProcessor::setBars: bars must be greater than 0. Setting to 0.";
qWarning() << "CavaProcessor::setBars: bars must be greater than 0. "
"Setting to 0.";
bars = 0;
}
@@ -100,13 +100,15 @@ void CavaProcessor::initCava() {
}
CavaProvider::CavaProvider(QObject* parent)
: AudioProvider(parent)
, m_bars(0)
, m_values(m_bars, 0.0) {
: AudioProvider(parent), m_bars(0), m_values(m_bars, 0.0) {
m_processor = new CavaProcessor();
init();
connect(static_cast<CavaProcessor*>(m_processor), &CavaProcessor::valuesChanged, this, &CavaProvider::updateValues);
connect(
static_cast<CavaProcessor*>(m_processor),
&CavaProcessor::valuesChanged,
this,
&CavaProvider::updateValues);
}
int CavaProvider::bars() const {
@@ -115,7 +117,8 @@ int CavaProvider::bars() const {
void CavaProvider::setBars(int bars) {
if (bars < 0) {
qWarning() << "CavaProvider::setBars: bars must be greater than 0. Setting to 0.";
qWarning() << "CavaProvider::setBars: bars must be greater than 0. "
"Setting to 0.";
bars = 0;
}
@@ -129,7 +132,10 @@ void CavaProvider::setBars(int bars) {
emit valuesChanged();
QMetaObject::invokeMethod(
static_cast<CavaProcessor*>(m_processor), &CavaProcessor::setBars, Qt::QueuedConnection, bars);
static_cast<CavaProcessor*>(m_processor),
&CavaProcessor::setBars,
Qt::QueuedConnection,
bars);
}
QVector<double> CavaProvider::values() const {
+34 -34
View File
@@ -7,58 +7,58 @@
namespace ZShell::services {
class CavaProcessor : public AudioProcessor {
Q_OBJECT
Q_OBJECT
public:
explicit CavaProcessor(QObject* parent = nullptr);
~CavaProcessor() override;
public:
explicit CavaProcessor(QObject* parent = nullptr);
~CavaProcessor() override;
void setBars(int bars);
void setBars(int bars);
signals:
void valuesChanged(QVector<double> values);
signals:
void valuesChanged(QVector<double> values);
protected:
void process() override;
protected:
void process() override;
private:
struct cava_plan* m_plan;
double* m_in;
double* m_out;
private:
struct cava_plan* m_plan;
double* m_in;
double* m_out;
int m_bars;
QVector<double> m_values;
int m_bars;
QVector<double> m_values;
void reload();
void initCava();
void cleanup();
void reload();
void initCava();
void cleanup();
};
class CavaProvider : public AudioProvider {
Q_OBJECT
QML_ELEMENT
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(int bars READ bars WRITE setBars NOTIFY barsChanged)
Q_PROPERTY(int bars READ bars WRITE setBars NOTIFY barsChanged)
Q_PROPERTY(QVector<double> values READ values NOTIFY valuesChanged)
Q_PROPERTY(QVector<double> values READ values NOTIFY valuesChanged)
public:
explicit CavaProvider(QObject* parent = nullptr);
public:
explicit CavaProvider(QObject* parent = nullptr);
[[nodiscard]] int bars() const;
void setBars(int bars);
[[nodiscard]] int bars() const;
void setBars(int bars);
[[nodiscard]] QVector<double> values() const;
[[nodiscard]] QVector<double> values() const;
signals:
void barsChanged();
void valuesChanged();
signals:
void barsChanged();
void valuesChanged();
private:
int m_bars;
QVector<double> m_values;
private:
int m_bars;
QVector<double> m_values;
void updateValues(QVector<double> values);
void updateValues(QVector<double> values);
};
} // namespace ZShell::services
+12 -7
View File
@@ -8,8 +8,7 @@
namespace ZShell::services {
Cpu::Cpu(QObject* parent)
: TickingService(parent) {
Cpu::Cpu(QObject* parent) : TickingService(parent) {
readNameOnce();
}
@@ -41,7 +40,8 @@ void Cpu::readNameOnce() {
const QByteArray data = f.readAll();
f.close();
static const QRegularExpression re(QStringLiteral("model name\\s*:\\s*(.+)"));
static const QRegularExpression re(
QStringLiteral("model name\\s*:\\s*(.+)"));
const auto match = re.match(QString::fromLatin1(data));
if (!match.hasMatch()) {
return;
@@ -64,8 +64,9 @@ void Cpu::refreshPercentage() {
const QByteArray data = f.readAll();
f.close();
static const QRegularExpression re(
QStringLiteral("^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"));
static const QRegularExpression re(QStringLiteral(
"^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"
"\\s+(\\d+)\\s+(\\d+)"));
const auto match = re.match(QString::fromLatin1(data));
if (!match.hasMatch()) {
return;
@@ -83,7 +84,10 @@ void Cpu::refreshPercentage() {
const quint64 totalDiff = total > m_lastTotal ? total - m_lastTotal : 0;
const quint64 idleDiff = idle > m_lastIdle ? idle - m_lastIdle : 0;
const qreal newPerc = totalDiff > 0 ? 1.0 - static_cast<qreal>(idleDiff) / static_cast<qreal>(totalDiff) : 0.0;
const qreal newPerc =
totalDiff > 0
? 1.0 - static_cast<qreal>(idleDiff) / static_cast<qreal>(totalDiff)
: 0.0;
m_lastTotal = total;
m_lastIdle = idle;
@@ -105,7 +109,8 @@ void Cpu::refreshTemperature() {
QString Cpu::cleanName(QString s) {
static const QRegularExpression noise(
QStringLiteral("\\(R\\)|\\(TM\\)|CPU|\\d+(?:th|nd|rd|st) Gen |Core |Processor"),
QStringLiteral(
"\\(R\\)|\\(TM\\)|CPU|\\d+(?:th|nd|rd|st) Gen |Core |Processor"),
QRegularExpression::CaseInsensitiveOption);
static const QRegularExpression spaces(QStringLiteral("\\s+"));
+28 -28
View File
@@ -7,42 +7,42 @@
namespace ZShell::services {
class Cpu : public TickingService {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged)
public:
explicit Cpu(QObject* parent = nullptr);
public:
explicit Cpu(QObject* parent = nullptr);
[[nodiscard]] QString name() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] qreal temperature() const;
[[nodiscard]] QString name() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] qreal temperature() const;
signals:
void nameChanged();
void percentageChanged();
void temperatureChanged();
signals:
void nameChanged();
void percentageChanged();
void temperatureChanged();
protected:
void tick() override;
protected:
void tick() override;
private:
void readNameOnce();
void refreshPercentage();
void refreshTemperature();
private:
void readNameOnce();
void refreshPercentage();
void refreshTemperature();
[[nodiscard]] static QString cleanName(QString s);
[[nodiscard]] static QString cleanName(QString s);
QString m_name;
qreal m_percentage = 0.0;
qreal m_temperature = 0.0;
quint64 m_lastIdle = 0;
quint64 m_lastTotal = 0;
bool m_nameLoaded = false;
QString m_name;
qreal m_percentage = 0.0;
qreal m_temperature = 0.0;
quint64 m_lastIdle = 0;
quint64 m_lastTotal = 0;
bool m_nameLoaded = false;
};
} // namespace ZShell::services
+51 -43
View File
@@ -17,49 +17,57 @@ struct DesktopItem {
};
class DesktopModel : public QAbstractListModel {
Q_OBJECT
QML_ELEMENT
Q_OBJECT
QML_ELEMENT
public:
enum DesktopRoles {
FileNameRole = Qt::UserRole + 1,
FilePathRole,
IsDirRole,
GridXRole,
GridYRole
public:
enum DesktopRoles {
FileNameRole = Qt::UserRole + 1,
FilePathRole,
IsDirRole,
GridXRole,
GridYRole
};
explicit DesktopModel(QObject* parent = nullptr);
[[nodiscard]] int rowCount(
const QModelIndex& parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(
const QModelIndex& index, int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void loadDirectory(const QString& path);
Q_INVOKABLE void moveIcon(int index, int newX, int newY);
Q_INVOKABLE void massMove(
const QVariantList& selectedPathsList,
const QString& leaderPath,
int targetX,
int targetY,
int maxCol,
int maxRow);
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
[[nodiscard]] int rows() const { return m_rows; }
void setRows(int r) {
if (m_rows != r) {
m_rows = r;
emit rowsChanged();
}
}
signals:
void rowsChanged();
private:
int m_rows = 1;
QList<DesktopItem> m_items;
QString m_watchedPath;
QFileSystemWatcher m_watcher;
void saveCurrentLayout();
[[nodiscard]] QPoint getEmptySpot(const QSet<QString>& occupied) const;
void onDirectoryChanged();
};
explicit DesktopModel(QObject *parent = nullptr);
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void loadDirectory(const QString &path);
Q_INVOKABLE void moveIcon(int index, int newX, int newY);
Q_INVOKABLE void massMove(const QVariantList &selectedPathsList, const QString &leaderPath, int targetX, int targetY, int maxCol, int maxRow);
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
public:
[[nodiscard]] int rows() const {
return m_rows;
}
void setRows(int r) {
if (m_rows != r) { m_rows = r; emit rowsChanged(); }
}
signals:
void rowsChanged();
private:
int m_rows = 1;
QList<DesktopItem> m_items;
QString m_watchedPath;
QFileSystemWatcher m_watcher;
void saveCurrentLayout();
[[nodiscard]] QPoint getEmptySpot(const QSet<QString> &occupied) const;
void onDirectoryChanged();
};
};
}; // namespace ZShell::services
@@ -9,11 +9,12 @@
namespace ZShell::services {
DesktopStateManager::DesktopStateManager(QObject *parent) : QObject(parent) {
}
DesktopStateManager::DesktopStateManager(QObject* parent) : QObject(parent) {}
QString DesktopStateManager::getConfigFilePath() const {
QString configDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/zshell";
QString configDir =
QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) +
"/zshell";
QDir dir(configDir);
if (!dir.exists()) {
dir.mkpath(".");
@@ -30,7 +31,8 @@ void DesktopStateManager::saveLayout(const QVariantMap& layout) {
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
} else {
qWarning() << "zshell: Cannot save desktop layout to" << getConfigFilePath();
qWarning() << "zshell: Cannot save desktop layout to"
<< getConfigFilePath();
}
}
@@ -7,18 +7,18 @@
namespace ZShell::services {
class DesktopStateManager : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
explicit DesktopStateManager(QObject *parent = nullptr);
public:
explicit DesktopStateManager(QObject* parent = nullptr);
Q_INVOKABLE void saveLayout(const QVariantMap& layout);
Q_INVOKABLE QVariantMap getLayout();
Q_INVOKABLE void saveLayout(const QVariantMap& layout);
Q_INVOKABLE QVariantMap getLayout();
private:
[[nodiscard]] QString getConfigFilePath() const;
private:
[[nodiscard]] QString getConfigFilePath() const;
};
} // namespace ZShell::services
+12 -5
View File
@@ -8,13 +8,17 @@ constexpr qreal kKib = 1024.0;
} // namespace
DiskInfo::DiskInfo(QString mount, quint64 usedBytes, quint64 totalBytes, bool hasRoot, QObject* parent)
DiskInfo::DiskInfo(
QString mount,
quint64 usedBytes,
quint64 totalBytes,
bool hasRoot,
QObject* parent)
: QObject(parent)
, m_mount(std::move(mount))
, m_usedBytes(usedBytes)
, m_totalBytes(totalBytes)
, m_hasRoot(hasRoot) {
}
, m_hasRoot(hasRoot) {}
QString DiskInfo::mount() const {
return m_mount;
@@ -29,12 +33,15 @@ qreal DiskInfo::total() const {
}
qreal DiskInfo::free() const {
const quint64 freeBytes = m_totalBytes > m_usedBytes ? m_totalBytes - m_usedBytes : 0;
const quint64 freeBytes =
m_totalBytes > m_usedBytes ? m_totalBytes - m_usedBytes : 0;
return static_cast<qreal>(freeBytes) / kKib;
}
qreal DiskInfo::perc() const {
return m_totalBytes > 0 ? static_cast<qreal>(m_usedBytes) / static_cast<qreal>(m_totalBytes) : 0.0;
return m_totalBytes > 0 ? static_cast<qreal>(m_usedBytes) /
static_cast<qreal>(m_totalBytes)
: 0.0;
}
bool DiskInfo::hasRoot() const {
+34 -29
View File
@@ -6,41 +6,46 @@
namespace ZShell::services {
class DiskInfo : public QObject {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("DiskInfo is created by DiskUsage")
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("DiskInfo is created by DiskUsage")
Q_PROPERTY(QString mount READ mount CONSTANT)
Q_PROPERTY(qreal used READ used NOTIFY usedChanged)
Q_PROPERTY(qreal total READ total NOTIFY totalChanged)
Q_PROPERTY(qreal free READ free NOTIFY freeChanged)
Q_PROPERTY(qreal perc READ perc NOTIFY percChanged)
Q_PROPERTY(bool hasRoot READ hasRoot NOTIFY hasRootChanged)
Q_PROPERTY(QString mount READ mount CONSTANT)
Q_PROPERTY(qreal used READ used NOTIFY usedChanged)
Q_PROPERTY(qreal total READ total NOTIFY totalChanged)
Q_PROPERTY(qreal free READ free NOTIFY freeChanged)
Q_PROPERTY(qreal perc READ perc NOTIFY percChanged)
Q_PROPERTY(bool hasRoot READ hasRoot NOTIFY hasRootChanged)
public:
DiskInfo(QString mount, quint64 usedBytes, quint64 totalBytes, bool hasRoot, QObject* parent = nullptr);
public:
DiskInfo(
QString mount,
quint64 usedBytes,
quint64 totalBytes,
bool hasRoot,
QObject* parent = nullptr);
[[nodiscard]] QString mount() const;
[[nodiscard]] qreal used() const;
[[nodiscard]] qreal total() const;
[[nodiscard]] qreal free() const;
[[nodiscard]] qreal perc() const;
[[nodiscard]] bool hasRoot() const;
[[nodiscard]] QString mount() const;
[[nodiscard]] qreal used() const;
[[nodiscard]] qreal total() const;
[[nodiscard]] qreal free() const;
[[nodiscard]] qreal perc() const;
[[nodiscard]] bool hasRoot() const;
void update(quint64 usedBytes, quint64 totalBytes, bool hasRoot);
void update(quint64 usedBytes, quint64 totalBytes, bool hasRoot);
signals:
void usedChanged();
void totalChanged();
void freeChanged();
void percChanged();
void hasRootChanged();
signals:
void usedChanged();
void totalChanged();
void freeChanged();
void percChanged();
void hasRootChanged();
private:
QString m_mount;
quint64 m_usedBytes;
quint64 m_totalBytes;
bool m_hasRoot;
private:
QString m_mount;
quint64 m_usedBytes;
quint64 m_totalBytes;
bool m_hasRoot;
};
} // namespace ZShell::services
+64 -64
View File
@@ -8,81 +8,81 @@
namespace ZShell::services {
class Gpu : public TickingService {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
enum Type {
Auto, // user override is empty (config "") — defer to detected autoType
None, // no usable GPU
Nvidia, // queried via nvidia-smi
Generic, // queried via /sys/class/drm/card*/device/gpu_busy_percent
};
Q_ENUM(Type)
public:
enum Type {
Auto, // user override is empty (config "") — defer to detected autoType
None, // no usable GPU
Nvidia, // queried via nvidia-smi
Generic, // queried via /sys/class/drm/card*/device/gpu_busy_percent
};
Q_ENUM(Type)
private:
Q_PROPERTY(Type type READ type NOTIFY typeChanged)
Q_PROPERTY(Type userType READ userType NOTIFY userTypeChanged)
Q_PROPERTY(Type autoType READ autoType NOTIFY autoTypeChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged)
Q_PROPERTY(qreal memoryUsed READ memoryUsed NOTIFY memoryUsedChanged)
Q_PROPERTY(qreal memoryTotal READ memoryTotal NOTIFY memoryTotalChanged)
private:
Q_PROPERTY(Type type READ type NOTIFY typeChanged)
Q_PROPERTY(Type userType READ userType NOTIFY userTypeChanged)
Q_PROPERTY(Type autoType READ autoType NOTIFY autoTypeChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(qreal temperature READ temperature NOTIFY temperatureChanged)
Q_PROPERTY(qreal memoryUsed READ memoryUsed NOTIFY memoryUsedChanged)
Q_PROPERTY(qreal memoryTotal READ memoryTotal NOTIFY memoryTotalChanged)
public:
explicit Gpu(QObject* parent = nullptr);
public:
explicit Gpu(QObject* parent = nullptr);
[[nodiscard]] Type type() const;
[[nodiscard]] Type userType() const;
[[nodiscard]] Type autoType() const;
[[nodiscard]] QString name() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] qreal temperature() const;
[[nodiscard]] qreal memoryUsed() const;
[[nodiscard]] qreal memoryTotal() const;
[[nodiscard]] Type type() const;
[[nodiscard]] Type userType() const;
[[nodiscard]] Type autoType() const;
[[nodiscard]] QString name() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] qreal temperature() const;
[[nodiscard]] qreal memoryUsed() const;
[[nodiscard]] qreal memoryTotal() const;
signals:
void typeChanged();
void userTypeChanged();
void autoTypeChanged();
void nameChanged();
void percentageChanged();
void temperatureChanged();
void memoryUsedChanged();
void memoryTotalChanged();
signals:
void typeChanged();
void userTypeChanged();
void autoTypeChanged();
void nameChanged();
void percentageChanged();
void temperatureChanged();
void memoryUsedChanged();
void memoryTotalChanged();
protected:
void tick() override;
protected:
void tick() override;
private:
void detectTypeOnce();
void detectNameOnce();
void readGenericUsage();
void startNvidiaUsage();
void readGpuTemperature();
private:
void detectTypeOnce();
void detectNameOnce();
void readGenericUsage();
void startNvidiaUsage();
void readGpuTemperature();
void setUserType(Type value);
void setAutoType(Type value);
void setName(QString value);
void setMemoryUsed(qreal value);
void setMemoryTotal(qreal value);
void setUserType(Type value);
void setAutoType(Type value);
void setName(QString value);
void setMemoryUsed(qreal value);
void setMemoryTotal(qreal value);
[[nodiscard]] static Type parseType(const QString& s);
[[nodiscard]] static QString cleanName(QString s);
[[nodiscard]] static Type parseType(const QString& s);
[[nodiscard]] static QString cleanName(QString s);
Type m_userType = Auto;
Type m_autoType = None;
QString m_name;
qreal m_percentage = 0.0;
qreal m_temperature = 0.0;
qreal m_memoryUsed = 0.0;
qreal m_memoryTotal = 0.0;
Type m_userType = Auto;
Type m_autoType = None;
QString m_name;
qreal m_percentage = 0.0;
qreal m_temperature = 0.0;
qreal m_memoryUsed = 0.0;
qreal m_memoryTotal = 0.0;
QProcess* m_typeProc = nullptr;
QProcess* m_nameProc = nullptr;
QProcess* m_nvidiaProc = nullptr;
QProcess* m_typeProc = nullptr;
QProcess* m_nameProc = nullptr;
QProcess* m_nvidiaProc = nullptr;
};
} // namespace ZShell::services
+19 -26
View File
@@ -9,14 +9,14 @@ namespace ZShell::services {
HyprsunsetManager::HyprsunsetManager(QObject* parent) : QObject(parent) {
connect(&m_timer, &QTimer::timeout, this, &HyprsunsetManager::apply);
connect(&m_manualTimer, &QTimer::timeout, this, [this] {
m_manualToggle = false;
emit manualToggleChanged();
apply();
});
m_manualToggle = false;
emit manualToggleChanged();
apply();
});
connect(&m_startCooldown, &QTimer::timeout, this, [this] {
m_startAllowed = true;
apply();
});
m_startAllowed = true;
apply();
});
m_startCooldown.start(2000);
m_manualTimer.setSingleShot(true);
@@ -51,16 +51,14 @@ int HyprsunsetManager::temp() const {
}
void HyprsunsetManager::setActiveAuto(bool activeAuto) {
if (activeAuto == m_activeAuto)
return;
if (activeAuto == m_activeAuto) return;
m_activeAuto = activeAuto;
emit activeAutoChanged();
}
void HyprsunsetManager::setManualToggle(bool toggle) {
if (toggle == m_manualToggle)
return;
if (toggle == m_manualToggle) return;
m_manualToggle = toggle;
emit manualToggleChanged();
@@ -69,8 +67,7 @@ void HyprsunsetManager::setManualToggle(bool toggle) {
}
void HyprsunsetManager::setEndTime(const int& time) {
if (time == m_endTime)
return;
if (time == m_endTime) return;
m_endTime = time;
emit endTimeChanged();
@@ -78,8 +75,7 @@ void HyprsunsetManager::setEndTime(const int& time) {
}
void HyprsunsetManager::setStartTime(const int& time) {
if (time == m_startTime)
return;
if (time == m_startTime) return;
m_startTime = time;
emit startTimeChanged();
@@ -87,8 +83,7 @@ void HyprsunsetManager::setStartTime(const int& time) {
}
void HyprsunsetManager::setTemp(const int& temp) {
if (temp == m_temp)
return;
if (temp == m_temp) return;
m_temp = temp;
emit tempChanged();
@@ -104,8 +99,7 @@ void HyprsunsetManager::toggle() {
}
void HyprsunsetManager::start() {
if (m_enabled && m_initialized)
return;
if (m_enabled && m_initialized) return;
m_initialized = true;
m_enabled = true;
@@ -113,13 +107,13 @@ void HyprsunsetManager::start() {
emit enabledChanged();
m_process.setProgram("hyprctl");
m_process.setArguments({"hyprsunset", "temperature", QString::number(m_temp)});
m_process.setArguments(
{"hyprsunset", "temperature", QString::number(m_temp)});
m_process.startDetached();
}
void HyprsunsetManager::end() {
if (!m_enabled && m_initialized)
return;
if (!m_enabled && m_initialized) return;
m_initialized = true;
m_enabled = false;
@@ -132,12 +126,11 @@ void HyprsunsetManager::end() {
}
void HyprsunsetManager::apply() {
if (m_manualToggle || !m_activeAuto || !m_startAllowed)
return;
if (m_manualToggle || !m_activeAuto || !m_startAllowed) return;
const auto current = QTime::currentTime();
const auto currentMin = current.hour() * 60 + current.minute();
bool isDarkTime;
bool isDarkTime = false;
if (m_startTime <= m_endTime) {
isDarkTime = (currentMin >= m_startTime && currentMin < m_endTime);
@@ -152,4 +145,4 @@ void HyprsunsetManager::apply() {
}
}
};
}; // namespace ZShell::services
+51 -46
View File
@@ -10,57 +10,62 @@
namespace ZShell::services {
class HyprsunsetManager : public QObject {
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(int endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged)
Q_PROPERTY(int temp READ temp WRITE setTemp NOTIFY tempChanged)
Q_PROPERTY(bool activeAuto READ activeAuto WRITE setActiveAuto NOTIFY activeAutoChanged)
Q_PROPERTY(bool manualToggle READ manualToggle WRITE setManualToggle NOTIFY manualToggleChanged)
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
Q_PROPERTY(
int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(int endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged)
Q_PROPERTY(int temp READ temp WRITE setTemp NOTIFY tempChanged)
Q_PROPERTY(
bool activeAuto READ activeAuto WRITE setActiveAuto NOTIFY
activeAutoChanged)
Q_PROPERTY(
bool manualToggle READ manualToggle WRITE setManualToggle NOTIFY
manualToggleChanged)
public:
explicit HyprsunsetManager(QObject* parent = nullptr);
public:
explicit HyprsunsetManager(QObject* parent = nullptr);
[[nodiscard]] int startTime() const;
[[nodiscard]] int endTime() const;
[[nodiscard]] bool enabled() const;
[[nodiscard]] int temp() const;
[[nodiscard]] bool activeAuto() const;
[[nodiscard]] bool manualToggle() const;
[[nodiscard]] int startTime() const;
[[nodiscard]] int endTime() const;
[[nodiscard]] bool enabled() const;
[[nodiscard]] int temp() const;
[[nodiscard]] bool activeAuto() const;
[[nodiscard]] bool manualToggle() const;
Q_INVOKABLE void toggle();
Q_INVOKABLE void apply();
Q_INVOKABLE void toggle();
Q_INVOKABLE void apply();
void setStartTime(const int& time);
void setEndTime(const int& time);
void setTemp(const int& temp);
void setActiveAuto(bool activeAuto);
void setManualToggle(bool toggle);
void setStartTime(const int& time);
void setEndTime(const int& time);
void setTemp(const int& temp);
void setActiveAuto(bool activeAuto);
void setManualToggle(bool toggle);
signals:
void enabledChanged();
void startTimeChanged();
void activeAutoChanged();
void endTimeChanged();
void tempChanged();
void manualToggleChanged();
signals:
void enabledChanged();
void startTimeChanged();
void activeAutoChanged();
void endTimeChanged();
void tempChanged();
void manualToggleChanged();
private:
int m_startTime;
int m_endTime;
bool m_enabled = false;
bool m_manualToggle = false;
bool m_activeAuto;
bool m_startAllowed = false;
bool m_initialized = false;
QTimer m_startCooldown;
int m_temp;
QProcess m_process;
QTimer m_timer;
QTimer m_manualTimer;
void start();
void end();
private:
int m_startTime;
int m_endTime;
bool m_enabled = false;
bool m_manualToggle = false;
bool m_activeAuto;
bool m_startAllowed = false;
bool m_initialized = false;
QTimer m_startCooldown;
int m_temp;
QProcess m_process;
QTimer m_timer;
QTimer m_manualTimer;
void start();
void end();
};
};
}; // namespace ZShell::services
+5 -5
View File
@@ -5,9 +5,7 @@
namespace ZShell::services {
Memory::Memory(QObject* parent)
: TickingService(parent) {
}
Memory::Memory(QObject* parent) : TickingService(parent) {}
qreal Memory::used() const {
return m_used;
@@ -29,8 +27,10 @@ void Memory::tick() {
const QByteArray data = f.readAll();
f.close();
static const QRegularExpression reTotal(QStringLiteral("MemTotal: *(\\d+)"));
static const QRegularExpression reAvail(QStringLiteral("MemAvailable: *(\\d+)"));
static const QRegularExpression reTotal(
QStringLiteral("MemTotal: *(\\d+)"));
static const QRegularExpression reAvail(
QStringLiteral("MemAvailable: *(\\d+)"));
const QString text = QString::fromLatin1(data);
const auto totalMatch = reTotal.match(text);
+20 -20
View File
@@ -8,32 +8,32 @@
namespace ZShell::services {
class Memory : public TickingService {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(qreal used READ used NOTIFY changed)
Q_PROPERTY(qreal total READ total NOTIFY changed)
Q_PROPERTY(qreal percentage READ percentage NOTIFY changed)
Q_PROPERTY(qreal used READ used NOTIFY changed)
Q_PROPERTY(qreal total READ total NOTIFY changed)
Q_PROPERTY(qreal percentage READ percentage NOTIFY changed)
public:
explicit Memory(QObject* parent = nullptr);
public:
explicit Memory(QObject* parent = nullptr);
[[nodiscard]] qreal used() const;
[[nodiscard]] qreal total() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] qreal used() const;
[[nodiscard]] qreal total() const;
[[nodiscard]] qreal percentage() const;
signals:
void changed();
signals:
void changed();
protected:
void tick() override;
protected:
void tick() override;
private:
qreal m_used = 0.0;
qreal m_total = 1.0;
quint64 m_lastUsed = 0;
quint64 m_lastTotal = 0;
private:
qreal m_used = 0.0;
qreal m_total = 1.0;
quint64 m_lastUsed = 0;
quint64 m_lastTotal = 0;
};
} // namespace ZShell::services
+32 -19
View File
@@ -14,7 +14,7 @@ namespace ZShell::services::sensorslib {
namespace {
std::atomic<bool> g_initOk{ false };
std::atomic<bool> g_initOk{false};
std::once_flag g_initFlag;
void doInit() {
@@ -25,14 +25,16 @@ void doInit() {
}
g_initOk.store(true, std::memory_order_release);
std::atexit([] {
if (g_initOk.load(std::memory_order_acquire)) {
sensors_cleanup();
}
});
if (g_initOk.load(std::memory_order_acquire)) {
sensors_cleanup();
}
});
}
[[nodiscard]] std::optional<double> readTempInput(const sensors_chip_name* chip, const sensors_feature* feat) {
const sensors_subfeature* sf = sensors_get_subfeature(chip, feat, SENSORS_SUBFEATURE_TEMP_INPUT);
[[nodiscard]] std::optional<double> readTempInput(
const sensors_chip_name* chip, const sensors_feature* feat) {
const sensors_subfeature* sf =
sensors_get_subfeature(chip, feat, SENSORS_SUBFEATURE_TEMP_INPUT);
if (!sf) {
return std::nullopt;
}
@@ -43,7 +45,8 @@ void doInit() {
return value;
}
[[nodiscard]] QByteArray featureLabel(const sensors_chip_name* chip, const sensors_feature* feat) {
[[nodiscard]] QByteArray featureLabel(
const sensors_chip_name* chip, const sensors_feature* feat) {
char* raw = sensors_get_label(chip, feat);
if (!raw) {
return {};
@@ -59,7 +62,8 @@ bool labelEquals(const QByteArray& label, const char* literal) {
bool labelStartsWith(const QByteArray& label, const char* prefix) {
const auto n = std::strlen(prefix);
return static_cast<size_t>(label.size()) >= n && std::memcmp(label.constData(), prefix, n) == 0;
return static_cast<size_t>(label.size()) >= n &&
std::memcmp(label.constData(), prefix, n) == 0;
}
} // namespace
@@ -74,13 +78,15 @@ std::optional<double> cpuPackageTemp() {
return std::nullopt;
}
std::optional<double> primary; // Package id N / Tdie
std::optional<double> primary; // Package id N / Tdie
std::optional<double> fallback; // Tctl
int chipNr = 0;
while (const sensors_chip_name* chip = sensors_get_detected_chips(nullptr, &chipNr)) {
while (const sensors_chip_name* chip =
sensors_get_detected_chips(nullptr, &chipNr)) {
int featNr = 0;
while (const sensors_feature* feat = sensors_get_features(chip, &featNr)) {
while (const sensors_feature* feat =
sensors_get_features(chip, &featNr)) {
if (feat->type != SENSORS_FEATURE_TEMP) {
continue;
}
@@ -89,7 +95,8 @@ std::optional<double> cpuPackageTemp() {
continue;
}
if (labelStartsWith(label, "Package id ") || labelEquals(label, "Tdie")) {
if (labelStartsWith(label, "Package id ") ||
labelEquals(label, "Tdie")) {
if (auto v = readTempInput(chip, feat)) {
primary = v;
}
@@ -116,13 +123,15 @@ std::optional<double> gpuPciAverageTemp() {
int countFallback = 0;
int chipNr = 0;
while (const sensors_chip_name* chip = sensors_get_detected_chips(nullptr, &chipNr)) {
while (const sensors_chip_name* chip =
sensors_get_detected_chips(nullptr, &chipNr)) {
if (chip->bus.type != SENSORS_BUS_TYPE_PCI) {
continue;
}
int featNr = 0;
while (const sensors_feature* feat = sensors_get_features(chip, &featNr)) {
while (const sensors_feature* feat =
sensors_get_features(chip, &featNr)) {
if (feat->type != SENSORS_FEATURE_TEMP) {
continue;
}
@@ -131,10 +140,14 @@ std::optional<double> gpuPciAverageTemp() {
continue;
}
const bool tempIndexed = labelStartsWith(label, "temp") && label.size() > 4 &&
std::isdigit(static_cast<unsigned char>(label[4]));
const bool isPrimary = tempIndexed || labelEquals(label, "GPU core") || labelEquals(label, "edge");
const bool isFallback = labelEquals(label, "junction") || labelEquals(label, "mem");
const bool tempIndexed =
labelStartsWith(label, "temp") && label.size() > 4 &&
std::isdigit(static_cast<unsigned char>(label[4]));
const bool isPrimary = tempIndexed ||
labelEquals(label, "GPU core") ||
labelEquals(label, "edge");
const bool isFallback = labelEquals(label, "junction") ||
labelEquals(label, "mem");
if (!isPrimary && !isFallback) {
continue;
+1 -3
View File
@@ -5,9 +5,7 @@
namespace ZShell::services {
Service::Service(QObject* parent)
: QObject(parent) {
}
Service::Service(QObject* parent) : QObject(parent) {}
void Service::ref(QObject* sender) {
if (m_refs.isEmpty()) {
+9 -9
View File
@@ -6,19 +6,19 @@
namespace ZShell::services {
class Service : public QObject {
Q_OBJECT
Q_OBJECT
public:
explicit Service(QObject* parent = nullptr);
public:
explicit Service(QObject* parent = nullptr);
void ref(QObject* sender);
void unref(QObject* sender);
void ref(QObject* sender);
void unref(QObject* sender);
private:
QSet<QObject*> m_refs;
private:
QSet<QObject*> m_refs;
virtual void start() = 0;
virtual void stop() = 0;
virtual void start() = 0;
virtual void stop() = 0;
};
} // namespace ZShell::services
+1 -2
View File
@@ -5,8 +5,7 @@
namespace ZShell::services {
ServiceRef::ServiceRef(Service* service, QObject* parent)
: QObject(parent)
, m_service(service) {
: QObject(parent), m_service(service) {
if (m_service) {
m_service->ref(this);
}
+13 -11
View File
@@ -7,22 +7,24 @@
namespace ZShell::services {
class ServiceRef : public QObject {
Q_OBJECT
QML_ELEMENT
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(ZShell::services::Service* service READ service WRITE setService NOTIFY serviceChanged)
Q_PROPERTY(
ZShell::services::Service* service READ service WRITE setService NOTIFY
serviceChanged)
public:
explicit ServiceRef(Service* service = nullptr, QObject* parent = nullptr);
public:
explicit ServiceRef(Service* service = nullptr, QObject* parent = nullptr);
[[nodiscard]] Service* service() const;
void setService(Service* service);
[[nodiscard]] Service* service() const;
void setService(Service* service);
signals:
void serviceChanged();
signals:
void serviceChanged();
private:
QPointer<Service> m_service;
private:
QPointer<Service> m_service;
};
} // namespace ZShell::services
+39 -41
View File
@@ -24,12 +24,14 @@ struct Accum {
};
[[nodiscard]] QString sysfsRealPath(uint major, uint minor) {
const QString link = QStringLiteral("/sys/dev/block/%1:%2").arg(major).arg(minor);
const QString link =
QStringLiteral("/sys/dev/block/%1:%2").arg(major).arg(minor);
const QString resolved = QFileInfo(link).canonicalFilePath();
return resolved;
}
[[nodiscard]] bool readDevtFromSysfs(const QString& sysfsBlockDir, uint& major, uint& minor) {
[[nodiscard]] bool readDevtFromSysfs(
const QString& sysfsBlockDir, uint& major, uint& minor) {
QFile f(sysfsBlockDir + QStringLiteral("/dev"));
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
@@ -50,6 +52,7 @@ struct Accum {
QStringList resolveByDevt(uint major, uint minor, int depth = 0);
// NOLINTNEXTLINE(misc-no-recursion)
QStringList resolveAtNode(const QString& node, int depth) {
if (node.isEmpty() || depth > 8) {
return {};
@@ -62,18 +65,20 @@ QStringList resolveAtNode(const QString& node, int depth) {
if (QFileInfo::exists(node + QStringLiteral("/partition"))) {
const QString diskNode = nodeInfo.path();
return { QFileInfo(diskNode).fileName() };
return {QFileInfo(diskNode).fileName()};
}
const QDir slavesDir(node + QStringLiteral("/slaves"));
if (slavesDir.exists()) {
const QStringList slaves = slavesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
const QStringList slaves =
slavesDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
if (!slaves.isEmpty()) {
QStringList out;
for (const QString& slave : slaves) {
uint sm = 0;
uint sn = 0;
const QString slaveDir = QStringLiteral("/sys/class/block/") + slave;
const QString slaveDir =
QStringLiteral("/sys/class/block/") + slave;
if (!readDevtFromSysfs(slaveDir, sm, sn)) {
continue;
}
@@ -88,18 +93,17 @@ QStringList resolveAtNode(const QString& node, int depth) {
}
}
return { nodeInfo.fileName() };
return {nodeInfo.fileName()};
}
// NOLINTNEXTLINE(misc-no-recursion)
QStringList resolveByDevt(uint major, uint minor, int depth) {
return resolveAtNode(sysfsRealPath(major, minor), depth);
}
} // namespace
Storage::Storage(QObject* parent)
: TickingService(parent) {
}
Storage::Storage(QObject* parent) : TickingService(parent) {}
qreal Storage::percentage() const {
qreal totalUsed = 0.0;
@@ -124,7 +128,8 @@ bool Storage::sameOrder(const QList<DiskInfo*>& a, const QList<DiskInfo*>& b) {
}
QQmlListProperty<DiskInfo> Storage::disksProp() {
return QQmlListProperty<DiskInfo>(this, nullptr, &Storage::disksCount, &Storage::disksAt);
return QQmlListProperty<DiskInfo>(
this, nullptr, &Storage::disksCount, &Storage::disksAt);
}
qsizetype Storage::disksCount(QQmlListProperty<DiskInfo>* prop) {
@@ -157,30 +162,11 @@ DiskInfo* Storage::primaryDisk() const {
bool Storage::isPseudoFs(QByteArrayView fsType) {
static constexpr const char* kPseudo[] = {
"tmpfs",
"devtmpfs",
"proc",
"sysfs",
"cgroup",
"cgroup2",
"overlay",
"squashfs",
"devpts",
"mqueue",
"ramfs",
"rpc_pipefs",
"autofs",
"configfs",
"debugfs",
"tracefs",
"securityfs",
"pstore",
"bpf",
"binfmt_misc",
"hugetlbfs",
"fusectl",
"efivarfs",
"selinuxfs",
"tmpfs", "devtmpfs", "proc", "sysfs", "cgroup",
"cgroup2", "overlay", "squashfs", "devpts", "mqueue",
"ramfs", "rpc_pipefs", "autofs", "configfs", "debugfs",
"tracefs", "securityfs", "pstore", "bpf", "binfmt_misc",
"hugetlbfs", "fusectl", "efivarfs", "selinuxfs",
};
for (const char* p : kPseudo) {
if (fsType == QByteArrayView(p)) {
@@ -194,7 +180,7 @@ QStringList Storage::resolveToPhysicalDisks(const QString& devicePath) {
if (devicePath.isEmpty() || !devicePath.startsWith(QLatin1Char('/'))) {
return {};
}
struct stat st {};
struct stat st{};
if (::stat(devicePath.toLocal8Bit().constData(), &st) != 0) {
return {};
}
@@ -232,7 +218,8 @@ void Storage::tick() {
const QByteArray device = v.device();
const auto totalBytes = static_cast<quint64>(v.bytesTotal());
const auto availBytes = static_cast<quint64>(v.bytesAvailable());
const quint64 usedBytes = totalBytes > availBytes ? totalBytes - availBytes : 0;
const quint64 usedBytes =
totalBytes > availBytes ? totalBytes - availBytes : 0;
const bool isRoot = v.rootPath() == QStringLiteral("/");
DeviceEntry& e = byDevice[device];
@@ -244,7 +231,8 @@ void Storage::tick() {
for (auto it = byDevice.constBegin(); it != byDevice.constEnd(); ++it) {
const DeviceEntry& e = it.value();
const QStringList disks = resolveToPhysicalDisks(QString::fromLocal8Bit(e.device));
const QStringList disks =
resolveToPhysicalDisks(QString::fromLocal8Bit(e.device));
if (disks.isEmpty()) {
continue;
}
@@ -269,14 +257,23 @@ void Storage::tick() {
next.reserve(byDisk.size());
for (auto it = byDisk.constBegin(); it != byDisk.constEnd(); ++it) {
if (DiskInfo* survivor = existing.take(it.key())) {
survivor->update(it.value().usedBytes, it.value().totalBytes, it.value().hasRoot);
survivor->update(
it.value().usedBytes,
it.value().totalBytes,
it.value().hasRoot);
next.append(survivor);
} else {
next.append(new DiskInfo(it.key(), it.value().usedBytes, it.value().totalBytes, it.value().hasRoot, this));
next.append(new DiskInfo(
it.key(),
it.value().usedBytes,
it.value().totalBytes,
it.value().hasRoot,
this));
}
}
std::sort(next.begin(), next.end(), [](const DiskInfo* a, const DiskInfo* b) {
std::sort(
next.begin(), next.end(), [](const DiskInfo* a, const DiskInfo* b) {
if (a->hasRoot() != b->hasRoot()) {
return a->hasRoot();
}
@@ -284,7 +281,8 @@ void Storage::tick() {
});
bool manualCleared = false;
if (DiskInfo* m = m_manualPrimaryDisk.data(); m && existing.contains(m->mount())) {
if (DiskInfo* m = m_manualPrimaryDisk.data();
m && existing.contains(m->mount())) {
m_manualPrimaryDisk.clear();
manualCleared = true;
}
+37 -30
View File
@@ -12,44 +12,51 @@
namespace ZShell::services {
class Storage : public TickingService {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(QQmlListProperty<ZShell::services::DiskInfo> disks READ disksProp NOTIFY disksChanged)
Q_PROPERTY(ZShell::services::DiskInfo* manualPrimaryDisk READ manualPrimaryDisk WRITE setManualPrimaryDisk NOTIFY
manualPrimaryDiskChanged)
Q_PROPERTY(ZShell::services::DiskInfo* primaryDisk READ primaryDisk NOTIFY primaryDiskChanged)
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged)
Q_PROPERTY(
QQmlListProperty<ZShell::services::DiskInfo> disks READ disksProp NOTIFY
disksChanged)
Q_PROPERTY(
ZShell::services::DiskInfo* manualPrimaryDisk READ manualPrimaryDisk
WRITE setManualPrimaryDisk NOTIFY manualPrimaryDiskChanged)
Q_PROPERTY(
ZShell::services::DiskInfo* primaryDisk READ primaryDisk NOTIFY
primaryDiskChanged)
public:
explicit Storage(QObject* parent = nullptr);
public:
explicit Storage(QObject* parent = nullptr);
[[nodiscard]] qreal percentage() const;
[[nodiscard]] QQmlListProperty<DiskInfo> disksProp();
[[nodiscard]] DiskInfo* manualPrimaryDisk() const;
void setManualPrimaryDisk(DiskInfo* disk);
[[nodiscard]] DiskInfo* primaryDisk() const;
[[nodiscard]] qreal percentage() const;
[[nodiscard]] QQmlListProperty<DiskInfo> disksProp();
[[nodiscard]] DiskInfo* manualPrimaryDisk() const;
void setManualPrimaryDisk(DiskInfo* disk);
[[nodiscard]] DiskInfo* primaryDisk() const;
signals:
void disksChanged();
void percentageChanged();
void manualPrimaryDiskChanged();
void primaryDiskChanged();
signals:
void disksChanged();
void percentageChanged();
void manualPrimaryDiskChanged();
void primaryDiskChanged();
protected:
void tick() override;
protected:
void tick() override;
private:
[[nodiscard]] static QStringList resolveToPhysicalDisks(const QString& devicePath);
[[nodiscard]] static bool isPseudoFs(QByteArrayView fsType);
[[nodiscard]] static bool sameOrder(const QList<DiskInfo*>& a, const QList<DiskInfo*>& b);
private:
[[nodiscard]] static QStringList resolveToPhysicalDisks(
const QString& devicePath);
[[nodiscard]] static bool isPseudoFs(QByteArrayView fsType);
[[nodiscard]] static bool sameOrder(
const QList<DiskInfo*>& a, const QList<DiskInfo*>& b);
static qsizetype disksCount(QQmlListProperty<DiskInfo>* prop);
static DiskInfo* disksAt(QQmlListProperty<DiskInfo>* prop, qsizetype i);
static qsizetype disksCount(QQmlListProperty<DiskInfo>* prop);
static DiskInfo* disksAt(QQmlListProperty<DiskInfo>* prop, qsizetype i);
QList<DiskInfo*> m_disks;
QPointer<DiskInfo> m_manualPrimaryDisk;
QList<DiskInfo*> m_disks;
QPointer<DiskInfo> m_manualPrimaryDisk;
};
} // namespace ZShell::services
+17 -16
View File
@@ -6,30 +6,31 @@
namespace ZShell::services {
class TickingService : public Service {
Q_OBJECT
Q_OBJECT
Q_PROPERTY(int updateInterval READ updateInterval NOTIFY updateIntervalChanged)
Q_PROPERTY(
int updateInterval READ updateInterval NOTIFY updateIntervalChanged)
public:
explicit TickingService(QObject* parent = nullptr);
public:
explicit TickingService(QObject* parent = nullptr);
[[nodiscard]] int updateInterval() const;
[[nodiscard]] int updateInterval() const;
signals:
void updateIntervalChanged();
signals:
void updateIntervalChanged();
protected:
void start() final;
void stop() final;
protected:
void start() final;
void stop() final;
virtual void tick() = 0;
virtual void tick() = 0;
private:
void applyInterval(int ms);
private:
void applyInterval(int ms);
QTimer* m_timer;
int m_interval = 1000;
bool m_running = false;
QTimer* m_timer;
int m_interval = 1000;
bool m_running = false;
};
} // namespace ZShell::services
+5 -5
View File
@@ -16,18 +16,18 @@ namespace ZShell::services::usagefmt {
FormatResult UsageFmt::formatKib(qreal kib, qreal total) const {
if (!finitePositive(kib) || !finitePositive(total)) {
return { 0.0, 0.0, "KiB" };
return {0.0, 0.0, "KiB"};
}
if (total >= kGib) {
return { kib / kGib, total / kGib, "TiB" };
return {kib / kGib, total / kGib, "TiB"};
}
if (total >= kMib) {
return { kib / kMib, total / kMib, "GiB" };
return {kib / kMib, total / kMib, "GiB"};
}
if (total >= kKib) {
return { kib / kKib, total / kKib, "MiB" };
return {kib / kKib, total / kKib, "MiB"};
}
return { kib, total, "KiB" };
return {kib, total, "KiB"};
}
} // namespace ZShell::services::usagefmt
+7 -6
View File
@@ -15,19 +15,20 @@ struct FormatResult {
Q_PROPERTY(qreal total MEMBER total CONSTANT)
Q_PROPERTY(QString unit MEMBER unit CONSTANT)
public:
public:
qreal value;
qreal total;
QString unit;
};
class UsageFmt : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
Q_INVOKABLE [[nodiscard]] FormatResult formatKib(qreal kib, qreal total) const;
public:
Q_INVOKABLE [[nodiscard]] FormatResult formatKib(
qreal kib, qreal total) const;
};
} // namespace ZShell::services::usagefmt