nixos-configs/modules/ags/config/ts/bar/items/workspaces.ts

180 lines
5.7 KiB
TypeScript
Raw Permalink Normal View History

const Hyprland = await Service.import('hyprland');
const { timeout } = Utils;
const { Box, Overlay, Revealer } = Widget;
2023-09-04 00:41:14 -04:00
import CursorBox from '../../misc/cursorbox.ts';
const URGENT_DURATION = 1000;
2024-01-13 11:15:08 -05:00
// Types
import {
BoxGeneric,
EventBoxGeneric,
OverlayGeneric,
RevealerGeneric,
Workspace,
} from 'global-types';
2023-12-20 03:45:05 -05:00
2023-12-18 18:00:30 -05:00
2024-01-13 11:15:08 -05:00
const Workspace = ({ id }: { id: number }) => {
return Revealer({
transition: 'slide_right',
2023-12-18 18:00:30 -05:00
attribute: { id },
child: CursorBox({
tooltip_text: `${id}`,
on_primary_click_release: () => {
2024-02-11 02:18:59 -05:00
Hyprland.messageAsync(`dispatch workspace ${id}`);
},
child: Box({
2023-11-06 18:37:23 -05:00
vpack: 'center',
2023-12-18 18:00:30 -05:00
class_name: 'button',
setup: (self) => {
const update = (
_: BoxGeneric,
addr: string | undefined,
) => {
2023-12-18 18:00:30 -05:00
const workspace = Hyprland.getWorkspace(id);
2023-12-20 03:45:05 -05:00
const occupied = workspace && workspace.windows > 0;
self.toggleClassName('occupied', occupied);
2023-12-18 18:00:30 -05:00
if (!addr) {
return;
}
// Deal with urgent windows
2023-12-18 18:00:30 -05:00
const client = Hyprland.getClient(addr);
const isThisUrgent = client &&
2023-12-20 03:45:05 -05:00
client.workspace.id === id;
2023-12-18 18:00:30 -05:00
if (isThisUrgent) {
self.toggleClassName('urgent', true);
// Only show for a sec when urgent is current workspace
2023-12-18 18:00:30 -05:00
if (Hyprland.active.workspace.id === id) {
timeout(URGENT_DURATION, () => {
self.toggleClassName('urgent', false);
});
}
}
};
self
2023-12-18 18:00:30 -05:00
.hook(Hyprland, update)
// Deal with urgent windows
2023-12-18 18:00:30 -05:00
.hook(Hyprland, update, 'urgent-window')
.hook(Hyprland.active.workspace, () => {
2023-12-18 18:00:30 -05:00
if (Hyprland.active.workspace.id === id) {
self.toggleClassName('urgent', false);
}
});
},
}),
}),
});
};
2023-09-04 00:41:14 -04:00
export default () => {
const L_PADDING = 16;
const WS_WIDTH = 30;
const updateHighlight = (self: BoxGeneric) => {
const currentId = Hyprland.active.workspace.id;
2023-12-20 03:45:05 -05:00
const indicators = (((self.get_parent() as OverlayGeneric)
.child as EventBoxGeneric)
.child as BoxGeneric)
.children as Workspace[];
2023-12-20 03:45:05 -05:00
const currentIndex = indicators
2023-12-18 18:00:30 -05:00
.findIndex((w) => w.attribute.id === currentId);
if (currentIndex < 0) {
return;
}
self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`);
};
const highlight = Box({
2023-11-06 18:37:23 -05:00
vpack: 'center',
hpack: 'start',
2023-12-18 18:00:30 -05:00
class_name: 'button active',
2023-12-18 18:00:30 -05:00
}).hook(Hyprland.active.workspace, updateHighlight);
const widget = Overlay({
pass_through: true,
overlays: [highlight],
child: CursorBox({
child: Box({
2023-12-18 18:00:30 -05:00
class_name: 'workspaces',
attribute: { workspaces: [] as Workspace[] },
2023-12-18 18:00:30 -05:00
setup: (self) => {
const refresh = () => {
(self.children as RevealerGeneric[])
.forEach((rev) => {
rev.reveal_child = false;
});
self.attribute.workspaces
.forEach((ws) => {
ws.reveal_child = true;
});
2023-12-18 18:00:30 -05:00
};
2023-12-18 18:00:30 -05:00
const updateWorkspaces = () => {
Hyprland.workspaces.forEach((ws) => {
const currentWs =
(self.children as Workspace[])
.find((ch) => ch.attribute.id === ws.id);
2023-12-20 03:45:05 -05:00
if (!currentWs && ws.id > 0) {
self.add(Workspace({ id: ws.id }));
}
});
self.show_all();
// Make sure the order is correct
self.attribute.workspaces.forEach((workspace, i) => {
(workspace.get_parent() as BoxGeneric)
.reorder_child(workspace, i);
2023-12-20 03:45:05 -05:00
});
2023-12-18 18:00:30 -05:00
};
self.hook(Hyprland, () => {
2023-12-18 18:00:30 -05:00
self.attribute.workspaces =
(self.children as Workspace[])
.filter((ch) => {
return Hyprland.workspaces.find((ws) => {
return ws.id === ch.attribute.id;
});
})
.sort((a, b) =>
a.attribute.id - b.attribute.id);
2023-09-04 00:41:14 -04:00
2023-12-18 18:00:30 -05:00
updateWorkspaces();
refresh();
// Make sure the highlight doesn't go too far
const TEMP_TIMEOUT = 10;
timeout(TEMP_TIMEOUT, () => updateHighlight(highlight));
});
},
}),
}),
});
return widget;
};