mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2025-12-12 19:46:20 +00:00
143 lines
4.2 KiB
JavaScript
143 lines
4.2 KiB
JavaScript
import App from "resource:///com/github/Aylur/ags/app.js";
|
|
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js";
|
|
import Applications from "resource:///com/github/Aylur/ags/service/applications.js";
|
|
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
|
import icons from "../icons.js";
|
|
import options from "../options.js";
|
|
import { launchApp, range } from "../utils.js";
|
|
|
|
const focus = ({ address }) =>
|
|
Hyprland.sendMessage(`dispatch focuswindow address:${address}`);
|
|
|
|
/** @param {import('types/widgets/button').ButtonProps & { icon: string, pinned?: boolean }} o */
|
|
const AppButton = ({ icon, pinned = false, ...rest }) => {
|
|
const indicators = Widget.Box({
|
|
vpack: "end",
|
|
hpack: "center",
|
|
children: range(5, 0).map(() =>
|
|
Widget.Box({
|
|
class_name: "indicator",
|
|
visible: false,
|
|
}),
|
|
),
|
|
});
|
|
|
|
return Widget.Button({
|
|
...rest,
|
|
attribute: indicators,
|
|
child: Widget.Box({
|
|
class_name: "box",
|
|
child: Widget.Overlay({
|
|
child: Widget.Icon({
|
|
icon,
|
|
size: options.desktop.dock.icon_size.bind("value"),
|
|
}),
|
|
pass_through: true,
|
|
overlays: pinned ? [indicators] : [],
|
|
}),
|
|
}),
|
|
});
|
|
};
|
|
|
|
const Taskbar = () =>
|
|
Widget.Box({
|
|
children: Hyprland.bind("clients").transform((c) =>
|
|
c.map((client) => {
|
|
for (const appName of options.desktop.dock.pinned_apps.value) {
|
|
if (client.class.toLowerCase().includes(appName.toLowerCase()))
|
|
return null;
|
|
}
|
|
for (const app of Applications.list) {
|
|
if (
|
|
(client.title && app.match(client.title)) ||
|
|
(client.class && app.match(client.class))
|
|
) {
|
|
return AppButton({
|
|
icon: app.icon_name || "",
|
|
tooltip_text: app.name,
|
|
on_primary_click: () => focus(client),
|
|
on_middle_click: () => launchApp(app),
|
|
});
|
|
}
|
|
}
|
|
}),
|
|
),
|
|
});
|
|
|
|
const PinnedApps = () =>
|
|
Widget.Box({
|
|
class_name: "pins",
|
|
homogeneous: true,
|
|
children: options.desktop.dock.pinned_apps.bind("value").transform((v) =>
|
|
v
|
|
.map((term) => ({ app: Applications.query(term)?.[0], term }))
|
|
.filter(({ app }) => app)
|
|
.map(({ app, term }) =>
|
|
AppButton({
|
|
pinned: true,
|
|
icon: app.icon_name || "",
|
|
on_primary_click: () => {
|
|
for (const client of Hyprland.clients) {
|
|
if (client.class.toLowerCase().includes(term))
|
|
return focus(client);
|
|
}
|
|
|
|
launchApp(app);
|
|
},
|
|
on_middle_click: () => launchApp(app),
|
|
tooltip_text: app.name,
|
|
setup: (button) =>
|
|
button.hook(Hyprland, () => {
|
|
const running = Hyprland.clients.filter((client) =>
|
|
client.class.toLowerCase().includes(term),
|
|
);
|
|
|
|
const focused = running.find(
|
|
(client) => client.address === Hyprland.active.client.address,
|
|
);
|
|
|
|
const index = running.findIndex((c) => c === focused);
|
|
|
|
for (let i = 0; i < 5; ++i) {
|
|
const indicator = button.attribute.children[i];
|
|
indicator.visible = i < running.length;
|
|
indicator.toggleClassName("focused", i === index);
|
|
}
|
|
|
|
button.set_tooltip_text(
|
|
running.length === 1 ? running[0].title : app.name,
|
|
);
|
|
}),
|
|
}),
|
|
),
|
|
),
|
|
});
|
|
|
|
export default () => {
|
|
const pinnedapps = PinnedApps();
|
|
const taskbar = Taskbar();
|
|
const applauncher = AppButton({
|
|
class_name: "launcher nonrunning",
|
|
icon: icons.apps.apps,
|
|
tooltip_text: "Applications",
|
|
on_clicked: () => App.toggleWindow("applauncher"),
|
|
});
|
|
const separator = Widget.Separator({
|
|
vpack: "center",
|
|
hpack: "center",
|
|
orientation: 1,
|
|
setup: (self) =>
|
|
self.hook(
|
|
taskbar,
|
|
() => {
|
|
self.visible = taskbar.children.length > 0;
|
|
},
|
|
"notify::children",
|
|
),
|
|
});
|
|
return Widget.Box({
|
|
class_name: "dock",
|
|
children: [applauncher, pinnedapps, separator, taskbar],
|
|
});
|
|
};
|