insane ags rework
This commit is contained in:
parent
c8c64c3828
commit
da656f0b04
|
@ -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
252
src/.config/ags/status.js
Normal 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,
|
||||
}),
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
18
src/.config/ags/tsconfig.json
Normal file
18
src/.config/ags/tsconfig.json
Normal 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
1
src/.config/ags/types
Symbolic link
|
@ -0,0 +1 @@
|
|||
/usr/share/com.github.Aylur.ags/types
|
Loading…
Reference in a new issue