testing ags
This commit is contained in:
62
home/core/gui/ags/windows/bar/main.js
Normal file
62
home/core/gui/ags/windows/bar/main.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import { App, Widget } from "../../imports.js";
|
||||
import Battery from "./modules/battery.js";
|
||||
import Bluetooth from "./modules/bluetooth.js";
|
||||
import Date from "./modules/date.js";
|
||||
import Music from "./modules/music.js";
|
||||
import Net from "./modules/net.js";
|
||||
import CpuRam from "./modules/cpu_ram.js";
|
||||
import Tray from "./modules/tray.js";
|
||||
import Workspaces from "./modules/workspaces.js";
|
||||
|
||||
const SystemInfo = () =>
|
||||
Widget.EventBox({
|
||||
className: "system-menu-toggler",
|
||||
onPrimaryClick: () => App.toggleWindow("system-menu"),
|
||||
|
||||
child: Widget.Box({
|
||||
children: [Net(), Bluetooth(), Battery()],
|
||||
}),
|
||||
}).hook(App, (self, window, visible) => {
|
||||
if (window === "system-menu") {
|
||||
self.toggleClassName("active", visible);
|
||||
}
|
||||
});
|
||||
|
||||
const Start = () =>
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
hpack: "start",
|
||||
children: [
|
||||
Workspaces(),
|
||||
// Indicators
|
||||
],
|
||||
});
|
||||
|
||||
const Center = () =>
|
||||
Widget.Box({
|
||||
children: [Music()],
|
||||
});
|
||||
|
||||
const End = () =>
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
|
||||
children: [Tray(), CpuRam(), SystemInfo(), Date()],
|
||||
});
|
||||
|
||||
export default () =>
|
||||
Widget.Window({
|
||||
monitor: 0,
|
||||
name: `bar`,
|
||||
anchor: ["bottom", "left", "right"],
|
||||
exclusivity: "exclusive",
|
||||
|
||||
child: Widget.CenterBox({
|
||||
className: "bar",
|
||||
|
||||
startWidget: Start(),
|
||||
centerWidget: Center(),
|
||||
endWidget: End(),
|
||||
}),
|
||||
});
|
||||
6
home/core/gui/ags/windows/bar/modules/battery.js
Normal file
6
home/core/gui/ags/windows/bar/modules/battery.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Battery, Widget } from "../../../imports.js";
|
||||
|
||||
export default () =>
|
||||
Widget.Icon({ className: "battery module" })
|
||||
.bind("icon", Battery, "icon-name")
|
||||
.bind("tooltip-text", Battery, "percent", (p) => `Battery on ${p}%`);
|
||||
10
home/core/gui/ags/windows/bar/modules/bluetooth.js
Normal file
10
home/core/gui/ags/windows/bar/modules/bluetooth.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Bluetooth, Widget } from "../../../imports.js";
|
||||
import {
|
||||
getBluetoothIcon,
|
||||
getBluetoothText,
|
||||
} from "../../../utils/bluetooth.js";
|
||||
|
||||
export default () =>
|
||||
Widget.Icon({ className: "bluetooth module" })
|
||||
.bind("icon", Bluetooth, "connected-devices", getBluetoothIcon)
|
||||
.bind("tooltip-text", Bluetooth, "connected-devices", getBluetoothText);
|
||||
70
home/core/gui/ags/windows/bar/modules/cpu_ram.js
Normal file
70
home/core/gui/ags/windows/bar/modules/cpu_ram.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Utils, Widget } from "../../../imports.js";
|
||||
|
||||
const Indicator = (props) =>
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
vpack: "center",
|
||||
|
||||
children: [
|
||||
Widget.Label({
|
||||
className: "type",
|
||||
label: props.type,
|
||||
}),
|
||||
Widget.Label({ className: "value" }).poll(2000, props.poll),
|
||||
],
|
||||
}).poll(2000, props.boxpoll);
|
||||
|
||||
const cpu = {
|
||||
type: "CPU",
|
||||
|
||||
poll: (self) =>
|
||||
Utils.execAsync([
|
||||
"sh",
|
||||
"-c",
|
||||
`top -bn1 | rg '%Cpu' | tail -1 | awk '{print 100-$8}'`,
|
||||
])
|
||||
.then((r) => (self.label = Math.round(Number(r)) + "%"))
|
||||
.catch((err) => print(err)),
|
||||
|
||||
boxpoll: (self) =>
|
||||
Utils.execAsync(["sh", "-c", "lscpu --parse=MHZ"])
|
||||
.then((r) => {
|
||||
const mhz = r.split("\n").slice(4);
|
||||
const freq = mhz.reduce((acc, e) => acc + Number(e), 0) / mhz.length;
|
||||
self.tooltipText = Math.round(freq) + " MHz";
|
||||
})
|
||||
.catch((err) => print(err)),
|
||||
};
|
||||
|
||||
const ram = {
|
||||
type: "MEM",
|
||||
poll: (self) =>
|
||||
Utils.execAsync([
|
||||
"sh",
|
||||
"-c",
|
||||
`free | tail -2 | head -1 | awk '{print $3/$2*100}'`,
|
||||
])
|
||||
.then((r) => (self.label = Math.round(Number(r)) + "%"))
|
||||
.catch((err) => print(err)),
|
||||
|
||||
boxpoll: (self) =>
|
||||
Utils.execAsync([
|
||||
"sh",
|
||||
"-c",
|
||||
"free --si -h | tail -2 | head -1 | awk '{print $3}'",
|
||||
])
|
||||
.then((r) => (self.tooltipText = r))
|
||||
.catch((err) => print(err)),
|
||||
};
|
||||
|
||||
export default () =>
|
||||
Widget.EventBox({
|
||||
onPrimaryClick: () => Utils.execAsync(["missioncenter"]),
|
||||
|
||||
child: Widget.Box({
|
||||
className: "system-info module",
|
||||
|
||||
children: [Indicator(cpu), Indicator(ram)],
|
||||
}),
|
||||
});
|
||||
10
home/core/gui/ags/windows/bar/modules/date.js
Normal file
10
home/core/gui/ags/windows/bar/modules/date.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Utils, Widget } from "../../../imports.js";
|
||||
|
||||
export default () =>
|
||||
Widget.EventBox({
|
||||
child: Widget.Label({ className: "date module" }).poll(1000, (self) =>
|
||||
Utils.execAsync(["date", "+%a %b %d %H:%M"]).then(
|
||||
(r) => (self.label = r),
|
||||
),
|
||||
),
|
||||
});
|
||||
40
home/core/gui/ags/windows/bar/modules/music.js
Normal file
40
home/core/gui/ags/windows/bar/modules/music.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Mpris, Widget } from "../../../imports.js";
|
||||
import App from "resource:///com/github/Aylur/ags/app.js";
|
||||
import { findPlayer } from "../../../utils/mpris.js";
|
||||
|
||||
const Cover = (player) =>
|
||||
Widget.Box({ className: "cover" }).bind(
|
||||
"css",
|
||||
player,
|
||||
"cover-path",
|
||||
(cover) => `background-image: url('${cover ?? ""}');`,
|
||||
);
|
||||
|
||||
const Title = (player) =>
|
||||
Widget.Label({ className: "title module" }).bind(
|
||||
"label",
|
||||
player,
|
||||
"track-title",
|
||||
(title) => ((title ?? "") == "Unknown title" ? "" : title),
|
||||
);
|
||||
|
||||
export const MusicBox = (player) =>
|
||||
Widget.Box({
|
||||
children: [Cover(player), Title(player)],
|
||||
});
|
||||
|
||||
export default () =>
|
||||
Widget.EventBox({
|
||||
className: "music",
|
||||
onPrimaryClick: () => App.toggleWindow("music"),
|
||||
})
|
||||
.hook(App, (self, window, visible) => {
|
||||
if (window === "music") {
|
||||
self.toggleClassName("active", visible);
|
||||
}
|
||||
})
|
||||
.bind("visible", Mpris, "players", (p) => p.length > 0)
|
||||
.bind("child", Mpris, "players", (players) => {
|
||||
if (players.length == 0) return Widget.Box();
|
||||
return MusicBox(findPlayer(players));
|
||||
});
|
||||
7
home/core/gui/ags/windows/bar/modules/net.js
Normal file
7
home/core/gui/ags/windows/bar/modules/net.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Network, Widget } from "../../../imports.js";
|
||||
import { getNetIcon, getNetText } from "../../../utils/net.js";
|
||||
|
||||
export default () =>
|
||||
Widget.Icon({ className: "net module" })
|
||||
.bind("icon", Network, "connectivity", getNetIcon)
|
||||
.bind("tooltip-text", Network, "connectivity", getNetText);
|
||||
47
home/core/gui/ags/windows/bar/modules/tray.js
Normal file
47
home/core/gui/ags/windows/bar/modules/tray.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import { SystemTray, Widget } from "../../../imports.js";
|
||||
import Gdk from "gi://Gdk?version=3.0";
|
||||
|
||||
const Item = (item) =>
|
||||
Widget.Button({
|
||||
child: Widget.Icon().bind("icon", item, "icon"),
|
||||
|
||||
onPrimaryClick: (_, ev) => {
|
||||
try {
|
||||
item.activate(ev);
|
||||
} catch (err) {
|
||||
print(err);
|
||||
}
|
||||
},
|
||||
|
||||
setup: (self) => {
|
||||
const id = item.menu?.connect("popped-up", (menu) => {
|
||||
self.toggleClassName("active");
|
||||
menu.connect("notify::visible", (menu) => {
|
||||
self.toggleClassName("active", menu.visible);
|
||||
});
|
||||
menu.disconnect(id);
|
||||
});
|
||||
|
||||
if (id) {
|
||||
self.connect("destroy", () => item.menu?.disconnect(id));
|
||||
}
|
||||
|
||||
self.bind("tooltip-markup", item, "tooltip-markup");
|
||||
},
|
||||
|
||||
onSecondaryClick: (btn) =>
|
||||
item.menu?.popup_at_widget(
|
||||
btn,
|
||||
Gdk.Gravity.SOUTH,
|
||||
Gdk.Gravity.NORTH,
|
||||
null,
|
||||
),
|
||||
});
|
||||
|
||||
export default () =>
|
||||
Widget.Box({ className: "tray module" }).bind(
|
||||
"children",
|
||||
SystemTray,
|
||||
"items",
|
||||
(items) => items.map(Item),
|
||||
);
|
||||
72
home/core/gui/ags/windows/bar/modules/workspaces.js
Normal file
72
home/core/gui/ags/windows/bar/modules/workspaces.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { Hyprland, Widget } from "../../../imports.js";
|
||||
import {
|
||||
added,
|
||||
changeWorkspace,
|
||||
DEFAULT_MONITOR,
|
||||
focusedSwitch,
|
||||
getLastWorkspaceId,
|
||||
moveWorkspace,
|
||||
removed,
|
||||
workspaceActive,
|
||||
} from "../../../utils/hyprland.js";
|
||||
|
||||
globalThis.hyprland = Hyprland;
|
||||
|
||||
const makeWorkspaces = () =>
|
||||
[...Array(10)].map((_, i) => {
|
||||
const id = i + 1;
|
||||
|
||||
return Widget.Button({
|
||||
onPrimaryClick: () => changeWorkspace(id),
|
||||
|
||||
visible: getLastWorkspaceId() >= id,
|
||||
|
||||
setup: (self) => {
|
||||
const ws = Hyprland.getWorkspace(id);
|
||||
self.id = id;
|
||||
self.active = workspaceActive(id);
|
||||
self.monitor = DEFAULT_MONITOR;
|
||||
|
||||
if (self.active) {
|
||||
self.monitor = {
|
||||
name: ws?.monitor ?? DEFAULT_MONITOR.name,
|
||||
id: ws?.monitorID ?? DEFAULT_MONITOR.id,
|
||||
};
|
||||
self.toggleClassName(`monitor${self.monitor.id}`, true);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export default () =>
|
||||
Widget.EventBox({
|
||||
onScrollUp: () => changeWorkspace("+1"),
|
||||
onScrollDown: () => changeWorkspace("-1"),
|
||||
|
||||
child: Widget.Box({
|
||||
className: "workspaces module",
|
||||
|
||||
// The Hyprland service is ready later than ags is done parsing the config,
|
||||
// so only build the widget when we receive a signal from it.
|
||||
setup: (self) => {
|
||||
const connID = Hyprland.connect("notify::workspaces", () => {
|
||||
Hyprland.disconnect(connID);
|
||||
|
||||
self.children = makeWorkspaces();
|
||||
self.lastFocused = Hyprland.active.workspace.id;
|
||||
self.biggestId = getLastWorkspaceId();
|
||||
self
|
||||
.hook(Hyprland.active.workspace, focusedSwitch)
|
||||
.hook(Hyprland, added, "workspace-added")
|
||||
.hook(Hyprland, removed, "workspace-removed")
|
||||
.hook(
|
||||
Hyprland,
|
||||
(self, name, data) => {
|
||||
if (name === "moveworkspace") moveWorkspace(self, data);
|
||||
},
|
||||
"event",
|
||||
);
|
||||
});
|
||||
},
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user