[AGS] Bar: Done (WiFi still missing, will be added at some later point)
This commit is contained in:
197
config/astal/components/bar/modules/Hyprland.tsx
Normal file
197
config/astal/components/bar/modules/Hyprland.tsx
Normal file
@@ -0,0 +1,197 @@
|
||||
import AstalTray from "gi://AstalTray";
|
||||
import { bind, GObject } from "astal";
|
||||
import AstalHyprland from "gi://AstalHyprland";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
|
||||
const SYNC = GObject.BindingFlags.SYNC_CREATE;
|
||||
|
||||
const SysTray = () => {
|
||||
const trayBox = new Gtk.Box({ cssClasses: ["bar-button"] });
|
||||
const tray = AstalTray.get_default();
|
||||
|
||||
const trayItems = new Map<string, Gtk.MenuButton>();
|
||||
const trayAddedHandler = tray.connect("item-added", (_, id) => {
|
||||
const item = tray.get_item(id);
|
||||
const popover = Gtk.PopoverMenu.new_from_model(item.menu_model);
|
||||
const icon = new Gtk.Image();
|
||||
const button = new Gtk.MenuButton({
|
||||
popover,
|
||||
child: icon,
|
||||
cssClasses: ["tray-item"],
|
||||
});
|
||||
|
||||
item.bind_property("gicon", icon, "gicon", SYNC);
|
||||
popover.insert_action_group("dbusmenu", item.action_group);
|
||||
item.connect("notify::action-group", () => {
|
||||
popover.insert_action_group("dbusmenu", item.action_group);
|
||||
});
|
||||
|
||||
trayItems.set(id, button);
|
||||
trayBox.append(button);
|
||||
});
|
||||
|
||||
const trayRemovedHandler = tray.connect("item-removed", (_, id) => {
|
||||
const button = trayItems.get(id);
|
||||
if (button) {
|
||||
trayBox.remove(button);
|
||||
button.run_dispose();
|
||||
trayItems.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
trayBox.connect("destroy", () => {
|
||||
tray.disconnect(trayAddedHandler);
|
||||
tray.disconnect(trayRemovedHandler);
|
||||
});
|
||||
|
||||
return trayBox;
|
||||
};
|
||||
|
||||
const Workspace = () => {
|
||||
const hypr = AstalHyprland.get_default();
|
||||
|
||||
return (
|
||||
<box>
|
||||
{bind(hypr, "workspaces").as(wss =>
|
||||
wss
|
||||
.filter(ws => !(ws.id >= -99 && ws.id <= -2)) // filter out special workspaces
|
||||
.sort((a, b) => a.id - b.id)
|
||||
.map(ws => (
|
||||
<button
|
||||
cssClasses={bind(hypr, "focusedWorkspace").as(fw =>
|
||||
ws === fw
|
||||
? [
|
||||
"focused-workspace-button",
|
||||
"workspace-button",
|
||||
]
|
||||
: ["workspace-button"],
|
||||
)}
|
||||
onButtonPressed={() => ws.focus()}
|
||||
child={<label label={String(ws.id)}></label>}
|
||||
></button>
|
||||
)),
|
||||
)}
|
||||
</box>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays the name of the currently active window and provides a popover for
|
||||
* displaying all available clients
|
||||
*/
|
||||
const ActiveWindow = () => {
|
||||
const hypr = AstalHyprland.get_default();
|
||||
const focused = bind(hypr, "focusedClient");
|
||||
|
||||
const WindowPopover = (): Gtk.Popover => {
|
||||
// Set up boxes + Popover
|
||||
const clients = new Map<string, Gtk.Button>();
|
||||
const popover = new Gtk.Popover();
|
||||
const popoverBox = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
});
|
||||
|
||||
const widgetTitle = new Gtk.Label({
|
||||
cssClasses: ["title-2"],
|
||||
label: "Available Windows",
|
||||
});
|
||||
|
||||
popoverBox.append(widgetTitle);
|
||||
|
||||
const seaparator = new Gtk.Separator({
|
||||
marginTop: 5,
|
||||
marginBottom: 10,
|
||||
});
|
||||
|
||||
popoverBox.append(seaparator);
|
||||
|
||||
const addClient = (client: AstalHyprland.Client) => {
|
||||
const clientBox = new Gtk.Box();
|
||||
|
||||
// Workspace description
|
||||
const descWS = new Gtk.Label({ label: "(WS " });
|
||||
|
||||
// Workpsace information
|
||||
const workspace = new Gtk.Label();
|
||||
client.workspace.bind_property("name", workspace, "label", SYNC);
|
||||
|
||||
const windowClassDesc = new Gtk.Label({ label: ") [" });
|
||||
|
||||
const windowClass = new Gtk.Label();
|
||||
windowClass.label = client.get_initial_class();
|
||||
|
||||
const titleDesc = new Gtk.Label({ label: "] " });
|
||||
titleDesc.set_margin_end(2);
|
||||
|
||||
const title = new Gtk.Label();
|
||||
client.bind_property("title", title, "label", SYNC);
|
||||
|
||||
clientBox.append(descWS);
|
||||
clientBox.append(workspace);
|
||||
clientBox.append(windowClassDesc);
|
||||
clientBox.append(windowClass);
|
||||
clientBox.append(titleDesc);
|
||||
clientBox.append(title);
|
||||
|
||||
const button = new Gtk.Button();
|
||||
button.connect( 'clicked', () => {
|
||||
client.workspace.focus();
|
||||
} );
|
||||
button.set_child(clientBox);
|
||||
|
||||
popoverBox.append(button);
|
||||
|
||||
clients.set(client.get_address(), button);
|
||||
};
|
||||
|
||||
// Populate with already added clients
|
||||
const c = hypr.get_clients();
|
||||
for (let index = 0; index < c.length; index++) {
|
||||
addClient(c[index]);
|
||||
}
|
||||
|
||||
hypr.connect("client-added", (_, client) => {
|
||||
addClient(client);
|
||||
});
|
||||
|
||||
hypr.connect("client-removed", (_, client) => {
|
||||
const c = clients.get(client);
|
||||
if (c) {
|
||||
popoverBox.remove(c);
|
||||
c.run_dispose();
|
||||
clients.delete(client);
|
||||
}
|
||||
});
|
||||
|
||||
popover.set_child(popoverBox);
|
||||
return popover;
|
||||
};
|
||||
|
||||
const windowPopover = WindowPopover();
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
// Return fully assembled HyprlandFocusedClient box
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
return (
|
||||
<box visible={focused.as(Boolean)}>
|
||||
<button
|
||||
onClicked={() => windowPopover.popup()}
|
||||
cssClasses={["bar-button"]}
|
||||
>
|
||||
{focused.as(
|
||||
client =>
|
||||
client && (
|
||||
<label label={bind(client, "title").as(String)} />
|
||||
),
|
||||
)}
|
||||
</button>
|
||||
{windowPopover}
|
||||
</box>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
Workspace,
|
||||
ActiveWindow,
|
||||
SysTray,
|
||||
};
|
Reference in New Issue
Block a user