insane ags rework

This commit is contained in:
Soph :3 2024-07-31 05:37:59 +03:00
parent c8c64c3828
commit da656f0b04
Signed by: sophie
GPG key ID: EDA5D222A0C270F2
5 changed files with 332 additions and 39 deletions

View file

@ -1,4 +1,5 @@
import { NotificationPopups } from "./notificationPopups.js";
import { StatusWidget } from "./status.js";
const hyprland = await Service.import("hyprland");
const notifications = await Service.import("notifications");
@ -22,7 +23,7 @@ function Workspaces(monitor) {
.as((ws) => {
const g = ws.filter((z) => z.monitorID == monitor);
g.sort((a,b) => a.id - b.id)
g.sort((a, b) => a.id - b.id);
return g.map(({ id }) =>
Widget.Button({
on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`),
@ -55,8 +56,13 @@ function Clock() {
function Media() {
const label = Utils.watch("", mpris, "player-changed", () => {
const player = mpris.players.find((z) => z.entry == "spotify");
if (player) {
const ms = player.metadata["mpris:length"] / 1000;
let length = player.metadata["mpris:length"];
if(!length) length = 0;
const ms = length / 1000;
const minutes = Math.floor(ms / 1000 / 60);
const seconds = Math.floor((ms / 1000) % 60);
@ -194,7 +200,13 @@ function Bar(monitor = 0) {
App.config({
style: "./style.css",
windows: [Bar(0), Bar(1), NotificationPopups(0), NotificationPopups(1)],
windows: [
StatusWidget(1),
Bar(0),
Bar(1),
NotificationPopups(0),
NotificationPopups(1),
],
});
export {};

252
src/.config/ags/status.js Normal file
View file

@ -0,0 +1,252 @@
function humanFileSize(size) {
var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
return (
+(size / Math.pow(1024, i)).toFixed(2) * 1 +
" " +
["B", "kB", "MB", "GB", "TB"][i]
);
}
const uptimeVar = Variable("", {
poll: [60000, "uptime -p"],
});
const loadAverage = Variable("", {
poll: [
1000,
"uptime",
(e) => {
const a = e.split(" ").at(-1);
if (!a) return "Incorrect uptime command!";
return a
.replace("load average: ", "")
.split(" ")
.map((z) => z.replace(",", "."))
.join(" ");
},
],
});
const processCount = Variable(0, {
poll: [5000, "ps -Al", (e) => e.split("\n").length],
});
const freeKBMemory = Variable(0, {
poll: [1000, "awk '/MemFree/ { printf $2 }' /proc/meminfo", (e) => +e],
});
const psStats = Variable([], {
poll: [
2000,
"ps wwxo comm,pid,%cpu,%mem --sort -%mem",
(e) => {
return e
.split("\n")
.slice(1, 5)
.map((z) => {
return z
.replace(/^([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*)$/gm, "$1,$2,$3,$4")
.split(",");
});
},
],
});
export function StatusWidget(monitor = 0) {
const totalKBMem = +Utils.exec(
"awk '/MemTotal/ { printf $2 }' /proc/meminfo"
);
const unameR = Utils.exec("uname -r");
let df = Utils.exec("df")
.split("\n")
.filter((z) => z.startsWith("/dev/"))
.map((z) => {
const data = z
.replace(/^(\/dev\/[^ ]*) +(\d*) +(\d*) +(\d*).*$/gm, "$1,$2,$3,$4")
.split(",");
return {
file: data[0],
total: +data[1],
used: +data[2],
available: +data[3],
};
});
const linuxLabel = Widget.Label({
label: "Linux " + unameR,
hpack: "start"
});
const uptime = Widget.Box({
children: [
Widget.Label({
label: "Uptime: ",
class_name: "gray"
}),
Widget.Label({
label: uptimeVar.bind(),
}),
],
});
const ramUsage = Widget.Box({
vertical: true,
children: [
Widget.Box({
children: [
Widget.Label({
label: "RAM Usage: ",
class_name: "gray"
}),
Widget.Label({
label: freeKBMemory.bind().as((freeKb) => {
const used = totalKBMem - freeKb;
return (
humanFileSize(used * 1000) +
"/" +
humanFileSize(totalKBMem * 1000) +
" - "
);
}),
}),
Widget.Label({
label: freeKBMemory.bind().as((freeKb) => {
const used = totalKBMem - freeKb;
return Math.floor((used / totalKBMem) * 100) + "% ";
}),
}),
],
}),
Widget.LevelBar({
widthRequest: 100,
className: "levelbar",
value: freeKBMemory.bind().as((freeKb) => {
const used = totalKBMem - freeKb;
return +used / totalKBMem;
}),
}),
],
});
const cpuUsage = Widget.Box({
children: [
Widget.Label({
label: "Average CPU load: ",
class_name: "gray"
}),
Widget.Label({
label: loadAverage.bind(),
}),
],
});
const processCountWidget = Widget.Box({
children: [
Widget.Label({
label: "Processes: ",
class_name: "gray"
}),
Widget.Label({
label: processCount.bind().as((z) => z.toString()),
}),
],
});
const storageWidget = Widget.Box({
vertical: true,
children: [
...df
.map((z) => {
return [
Widget.Label({
label: z.file,
hpack: "start",
class_name: "gray"
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
hpack: "start",
label:
" " +
humanFileSize(z.used * 1000) +
"/" +
humanFileSize(z.total * 1000),
}),
Widget.LevelBar({
className: "levelbar",
widthRequest: 100,
value: z.used / z.total,
}),
],
}),
];
})
.flat(),
],
});
const psWidget = Widget.Box({
vertical: true,
hpack: "center",
children: psStats.bind().as((z) => {
return [
Widget.Label({
label:
"Name" +
" ".repeat(15 - 4) +
"PID" +
" ".repeat(7 - 3) +
"%Mem " +
"%Cpu ",
class_name: "gray"
}),
...z.map((proc) => {
return Widget.Box({
children: proc.map((j) =>
Widget.Label({
hexpand: true,
label: j + "",
})
),
});
}),
];
}),
});
return Widget.Window({
name: `status-${monitor}`, // name has to be unique
class_name: "statusjs",
monitor,
anchor: ["top", "right"],
exclusivity: "exclusive",
layer: "background", // secret sauce
margins: [6, 6, 6, 6],
child: Widget.Box({
class_name: "status",
children: [
linuxLabel,
Widget.Label({
label: "-".repeat(40),
}),
uptime,
ramUsage,
cpuUsage,
processCountWidget,
Widget.Label({
label: "-".repeat(40),
}),
storageWidget,
Widget.Label({
label: "-".repeat(40),
}),
psWidget,
],
vertical: true,
}),
});
}

View file

@ -1,86 +1,96 @@
window.bar {
background-color: @theme_bg_color;
color: @theme_fg_color;
background-color: @theme_bg_color;
color: @theme_fg_color;
}
button {
min-width: 0;
padding-top: 0;
padding-bottom: 0;
background-color: transparent;
border: 0;
min-width: 0;
padding-top: 0;
padding-bottom: 0;
background-color: transparent;
border: 0;
}
button:active {
background-color: @theme_selected_bg_color;
background-color: @theme_selected_bg_color;
}
button:hover {
border-bottom: 3px solid @theme_fg_color;
border-bottom: 3px solid @theme_fg_color;
}
label {
font-weight: bold;
font-weight: bold;
}
window.notification-popups box.notifications {
padding: .5em;
padding: 0.5em;
}
.body {
color: @theme_unfocused_fg_color;
color: @theme_unfocused_fg_color;
}
.actions .action-button {
margin: 0 .4em;
margin-top: .8em;
margin: 0 0.4em;
margin-top: 0.8em;
}
.actions .action-button:first-child {
margin-left: 0;
margin-left: 0;
}
.actions .action-button:last-child {
margin-right: 0;
margin-right: 0;
}
.icon {
min-width: 68px;
min-height: 68px;
margin-right: 1em;
min-width: 68px;
min-height: 68px;
margin-right: 1em;
}
.icon image {
font-size: 58px;
/* to center the icon */
margin: 5px;
color: @theme_fg_color;
font-size: 58px;
/* to center the icon */
margin: 5px;
color: @theme_fg_color;
}
.icon box {
min-width: 68px;
min-height: 68px;
border-radius: 7px;
min-width: 68px;
min-height: 68px;
border-radius: 7px;
}
.workspaces button.focused {
border-bottom: 3px solid @theme_selected_bg_color;
border-bottom: 3px solid @theme_selected_bg_color;
}
.notification {
min-width: 350px;
border-radius: 11px;
padding: 1em;
margin: .5em;
border: 1px solid @wm_borders_edge;
background-color: @theme_bg_color;
min-width: 350px;
border-radius: 11px;
padding: 1em;
margin: 0.5em;
border: 1px solid @wm_borders_edge;
background-color: @theme_bg_color;
}
.client-title {
color: @theme_selected_bg_color;
color: @theme_selected_bg_color;
}
.status {
background-color: @theme_bg_color;
padding: 10px;
border-radius: 5px;
color: @theme_fg_color;
}
.gray {
color: @theme_unfocused_fg_color;
}
levelbar block,
highlight {
min-height: 10px;
}
min-height: 10px;
}

View file

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": [
"ES2022"
],
"allowJs": true,
"checkJs": true,
"strict": true,
"noImplicitAny": false,
"baseUrl": ".",
"typeRoots": [
"./types"
],
"skipLibCheck": true
}
}

1
src/.config/ags/types Symbolic link
View file

@ -0,0 +1 @@
/usr/share/com.github.Aylur.ags/types