summaryrefslogtreecommitdiff
path: root/src/services
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-30 21:31:19 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-30 21:31:19 +1100
commitad22dbdfebbb0def2ec2d8e2c91469e9a9e4fdf7 (patch)
tree826e715ae0aa7d4c5bcd29d76421a211b920dca1 /src/services
parentsideright: fix assertion row != -1 (diff)
downloadcaelestia-shell-ad22dbdfebbb0def2ec2d8e2c91469e9a9e4fdf7.tar.gz
caelestia-shell-ad22dbdfebbb0def2ec2d8e2c91469e9a9e4fdf7.tar.bz2
caelestia-shell-ad22dbdfebbb0def2ec2d8e2c91469e9a9e4fdf7.zip
sideleft: create popdown window
Diffstat (limited to 'src/services')
-rw-r--r--src/services/cpu.ts45
-rw-r--r--src/services/gpu.ts55
-rw-r--r--src/services/memory.ts60
-rw-r--r--src/services/storage.ts61
4 files changed, 221 insertions, 0 deletions
diff --git a/src/services/cpu.ts b/src/services/cpu.ts
new file mode 100644
index 0000000..f1699f7
--- /dev/null
+++ b/src/services/cpu.ts
@@ -0,0 +1,45 @@
+import { GObject, interval, property, register } from "astal";
+import { cpu as config } from "config";
+import GTop from "gi://GTop";
+
+@register({ GTypeName: "Cpu" })
+export default class Cpu extends GObject.Object {
+ static instance: Cpu;
+ static get_default() {
+ if (!this.instance) this.instance = new Cpu();
+
+ return this.instance;
+ }
+
+ #previous: GTop.glibtop_cpu = new GTop.glibtop_cpu();
+ #usage: number = 0;
+
+ @property(Number)
+ get usage() {
+ return this.#usage;
+ }
+
+ calculateUsage() {
+ const current = new GTop.glibtop_cpu();
+ GTop.glibtop_get_cpu(current);
+
+ // Calculate the differences from the previous to current data
+ const total = current.total - this.#previous.total;
+ const idle = current.idle - this.#previous.idle;
+
+ this.#previous = current;
+
+ return total > 0 ? ((total - idle) / total) * 100 : 0;
+ }
+
+ update() {
+ this.#usage = this.calculateUsage();
+ this.notify("usage");
+ }
+
+ constructor() {
+ super();
+
+ interval(config.interval, () => this.update());
+ }
+}
diff --git a/src/services/gpu.ts b/src/services/gpu.ts
new file mode 100644
index 0000000..916a2bc
--- /dev/null
+++ b/src/services/gpu.ts
@@ -0,0 +1,55 @@
+import { execAsync, Gio, GObject, interval, property, register } from "astal";
+import { gpu as config } from "config";
+
+@register({ GTypeName: "Gpu" })
+export default class Gpu extends GObject.Object {
+ static instance: Gpu;
+ static get_default() {
+ if (!this.instance) this.instance = new Gpu();
+
+ return this.instance;
+ }
+
+ readonly available: boolean = false;
+ #usage: number = 0;
+
+ @property(Number)
+ get usage() {
+ return this.#usage;
+ }
+
+ async calculateUsage() {
+ const percs = (await execAsync("fish -c 'cat /sys/class/drm/card*/device/gpu_busy_percent'")).split("\n");
+ return percs.reduce((a, b) => a + parseFloat(b), 0) / percs.length;
+ }
+
+ update() {
+ this.calculateUsage().then(usage => {
+ this.#usage = usage;
+ this.notify("usage");
+ });
+ }
+
+ constructor() {
+ super();
+
+ let enumerator = null;
+ try {
+ enumerator = Gio.File.new_for_path("/sys/class/drm").enumerate_children(
+ Gio.FILE_ATTRIBUTE_STANDARD_NAME,
+ Gio.FileQueryInfoFlags.NONE,
+ null
+ );
+ } catch {}
+
+ let info: Gio.FileInfo | undefined | null;
+ while ((info = enumerator?.next_file(null))) {
+ if (/card[0-9]+/.test(info.get_name())) {
+ this.available = true;
+ break;
+ }
+ }
+
+ if (this.available) interval(config.interval, () => this.update());
+ }
+}
diff --git a/src/services/memory.ts b/src/services/memory.ts
new file mode 100644
index 0000000..74fa228
--- /dev/null
+++ b/src/services/memory.ts
@@ -0,0 +1,60 @@
+import { GObject, interval, property, readFileAsync, register } from "astal";
+import { memory as config } from "config";
+
+@register({ GTypeName: "Memory" })
+export default class Memory extends GObject.Object {
+ static instance: Memory;
+ static get_default() {
+ if (!this.instance) this.instance = new Memory();
+
+ return this.instance;
+ }
+
+ #total: number = 0;
+ #free: number = 0;
+ #used: number = 0;
+ #usage: number = 0;
+
+ @property(Number)
+ get total() {
+ return this.#total;
+ }
+
+ @property(Number)
+ get free() {
+ return this.#free;
+ }
+
+ @property(Number)
+ get used() {
+ return this.#used;
+ }
+
+ @property(Number)
+ get usage() {
+ return this.#usage;
+ }
+
+ async update() {
+ const info = await readFileAsync("/proc/meminfo");
+ this.#total = parseInt(info.match(/MemTotal:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
+ this.#free = parseInt(info.match(/MemAvailable:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
+
+ if (isNaN(this.#total)) this.#total = 0;
+ if (isNaN(this.#free)) this.#free = 0;
+
+ this.#used = this.#total - this.#free;
+ this.#usage = this.#total > 0 ? (this.#used / this.#total) * 100 : 0;
+
+ this.notify("total");
+ this.notify("free");
+ this.notify("used");
+ this.notify("usage");
+ }
+
+ constructor() {
+ super();
+
+ interval(config.interval, () => this.update().catch(console.error));
+ }
+}
diff --git a/src/services/storage.ts b/src/services/storage.ts
new file mode 100644
index 0000000..e1e1c55
--- /dev/null
+++ b/src/services/storage.ts
@@ -0,0 +1,61 @@
+import { GObject, interval, property, register } from "astal";
+import { storage as config } from "config";
+import GTop from "gi://GTop";
+
+@register({ GTypeName: "Storage" })
+export default class Storage extends GObject.Object {
+ static instance: Storage;
+ static get_default() {
+ if (!this.instance) this.instance = new Storage();
+
+ return this.instance;
+ }
+
+ #total: number = 0;
+ #free: number = 0;
+ #used: number = 0;
+ #usage: number = 0;
+
+ @property(Number)
+ get total() {
+ return this.#total;
+ }
+
+ @property(Number)
+ get free() {
+ return this.#free;
+ }
+
+ @property(Number)
+ get used() {
+ return this.#used;
+ }
+
+ @property(Number)
+ get usage() {
+ return this.#usage;
+ }
+
+ update() {
+ const root = new GTop.glibtop_fsusage();
+ GTop.glibtop_get_fsusage(root, "/");
+ const home = new GTop.glibtop_fsusage();
+ GTop.glibtop_get_fsusage(home, "/home");
+
+ this.#total = root.blocks * root.block_size + home.blocks * home.block_size;
+ this.#free = root.bavail * root.block_size + home.bavail * home.block_size;
+ this.#used = this.#total - this.#free;
+ this.#usage = this.#total > 0 ? (this.#used / this.#total) * 100 : 0;
+
+ this.notify("total");
+ this.notify("free");
+ this.notify("used");
+ this.notify("usage");
+ }
+
+ constructor() {
+ super();
+
+ interval(config.interval, () => this.update());
+ }
+}