2023-10-31 08:32:40 -04:00
|
|
|
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-11-13 13:19:14 -05:00
|
|
|
import { timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
2023-10-31 08:32:40 -04:00
|
|
|
import { Box, Overlay, Revealer } from 'resource:///com/github/Aylur/ags/widget.js';
|
2023-09-04 00:41:14 -04:00
|
|
|
|
2024-01-13 23:38:31 -05:00
|
|
|
import CursorBox from '../../misc/cursorbox.ts';
|
2023-09-05 13:27:29 -04:00
|
|
|
|
2023-11-21 01:29:46 -05:00
|
|
|
const URGENT_DURATION = 1000;
|
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
// Types
|
2024-01-13 23:38:31 -05:00
|
|
|
import AgsBox from 'types/widgets/box.ts';
|
|
|
|
import AgsRevealer from 'types/widgets/revealer.ts';
|
|
|
|
import AgsOverlay from 'types/widgets/overlay.ts';
|
|
|
|
import AgsEventBox from 'types/widgets/eventbox.ts';
|
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 }) => {
|
2023-11-21 01:29:46 -05:00
|
|
|
return Revealer({
|
2023-10-20 23:11:21 -04:00
|
|
|
transition: 'slide_right',
|
2023-12-18 18:00:30 -05:00
|
|
|
attribute: { id },
|
2023-10-17 13:47:02 -04:00
|
|
|
|
2023-12-18 23:20:32 -05:00
|
|
|
child: CursorBox({
|
2023-12-19 12:28:29 -05:00
|
|
|
tooltip_text: `${id}`,
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-18 23:20:32 -05:00
|
|
|
on_primary_click_release: () => {
|
2023-12-18 18:00:30 -05:00
|
|
|
Hyprland.sendMessage(`dispatch workspace ${id}`);
|
2023-11-21 01:29:46 -05:00
|
|
|
},
|
|
|
|
|
2023-10-20 23:11:21 -04:00
|
|
|
child: Box({
|
2023-11-06 18:37:23 -05:00
|
|
|
vpack: 'center',
|
2023-12-18 18:00:30 -05:00
|
|
|
class_name: 'button',
|
2023-11-21 01:29:46 -05:00
|
|
|
|
|
|
|
setup: (self) => {
|
2024-01-13 11:15:08 -05:00
|
|
|
const update = (_: AgsBox, 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;
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-11-04 17:37:46 -04:00
|
|
|
self.toggleClassName('occupied', occupied);
|
|
|
|
|
2023-12-18 18:00:30 -05:00
|
|
|
if (!addr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-04 17:37:46 -04:00
|
|
|
// 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) {
|
2023-11-04 17:37:46 -04:00
|
|
|
self.toggleClassName('urgent', true);
|
2023-11-07 12:00:53 -05:00
|
|
|
|
|
|
|
// Only show for a sec when urgent is current workspace
|
2023-12-18 18:00:30 -05:00
|
|
|
if (Hyprland.active.workspace.id === id) {
|
2023-11-21 01:29:46 -05:00
|
|
|
timeout(URGENT_DURATION, () => {
|
|
|
|
self.toggleClassName('urgent', false);
|
|
|
|
});
|
|
|
|
}
|
2023-11-07 12:00:53 -05:00
|
|
|
}
|
2023-11-04 17:37:46 -04:00
|
|
|
};
|
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
self
|
2023-12-18 18:00:30 -05:00
|
|
|
.hook(Hyprland, update)
|
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
// Deal with urgent windows
|
2023-12-18 18:00:30 -05:00
|
|
|
.hook(Hyprland, update, 'urgent-window')
|
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
.hook(Hyprland.active.workspace, () => {
|
2023-12-18 18:00:30 -05:00
|
|
|
if (Hyprland.active.workspace.id === id) {
|
2023-12-17 00:01:58 -05:00
|
|
|
self.toggleClassName('urgent', false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2023-10-20 23:11:21 -04:00
|
|
|
}),
|
|
|
|
}),
|
|
|
|
});
|
2023-11-21 01:29:46 -05:00
|
|
|
};
|
2023-09-04 00:41:14 -04:00
|
|
|
|
2023-10-31 10:18:58 -04:00
|
|
|
export default () => {
|
2023-11-21 01:29:46 -05:00
|
|
|
const L_PADDING = 16;
|
|
|
|
const WS_WIDTH = 30;
|
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
const updateHighlight = (self: AgsBox) => {
|
2023-10-31 10:18:58 -04:00
|
|
|
const currentId = Hyprland.active.workspace.id;
|
2023-12-20 03:45:05 -05:00
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
const indicators = (((self.get_parent() as AgsOverlay)
|
|
|
|
.child as AgsEventBox)
|
|
|
|
.child as AgsBox)
|
|
|
|
.children as Array<AgsRevealer>;
|
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);
|
2023-10-31 10:18:58 -04:00
|
|
|
|
2023-11-21 01:29:46 -05:00
|
|
|
if (currentIndex < 0) {
|
2023-10-31 10:18:58 -04:00
|
|
|
return;
|
2023-11-21 01:29:46 -05:00
|
|
|
}
|
2023-10-31 10:18:58 -04:00
|
|
|
|
2023-11-21 01:29:46 -05:00
|
|
|
self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`);
|
2023-10-31 10:18:58 -04:00
|
|
|
};
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-10-31 10:18:58 -04:00
|
|
|
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-19 12:28:29 -05:00
|
|
|
|
2023-12-18 18:00:30 -05:00
|
|
|
}).hook(Hyprland.active.workspace, updateHighlight);
|
2023-10-29 13:40:37 -04:00
|
|
|
|
2023-10-31 10:18:58 -04:00
|
|
|
const widget = Overlay({
|
2023-11-15 16:24:42 -05:00
|
|
|
pass_through: true,
|
2023-10-31 10:18:58 -04:00
|
|
|
overlays: [highlight],
|
2023-12-18 23:20:32 -05:00
|
|
|
child: CursorBox({
|
2023-10-31 10:18:58 -04:00
|
|
|
child: Box({
|
2023-12-18 18:00:30 -05:00
|
|
|
class_name: 'workspaces',
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2024-01-13 11:15:08 -05:00
|
|
|
attribute: { workspaces: [] },
|
2023-09-20 20:25:52 -04:00
|
|
|
|
2023-12-18 18:00:30 -05:00
|
|
|
setup: (self) => {
|
2024-01-13 11:15:08 -05:00
|
|
|
const workspaces = (): Array<AgsRevealer> =>
|
|
|
|
self.attribute.workspaces;
|
2023-12-20 03:45:05 -05:00
|
|
|
|
2023-12-18 18:00:30 -05:00
|
|
|
const refresh = () => {
|
2024-01-13 11:15:08 -05:00
|
|
|
(self.children as Array<AgsRevealer>).forEach((rev) => {
|
2023-11-21 01:29:46 -05:00
|
|
|
rev.reveal_child = false;
|
|
|
|
});
|
2023-12-20 03:45:05 -05:00
|
|
|
|
|
|
|
workspaces().forEach((ws) => {
|
2023-12-19 12:28:29 -05:00
|
|
|
ws.reveal_child = true;
|
2023-10-31 10:18:58 -04:00
|
|
|
});
|
2023-12-18 18:00:30 -05:00
|
|
|
};
|
2023-09-20 20:25:52 -04:00
|
|
|
|
2023-12-18 18:00:30 -05:00
|
|
|
const updateWorkspaces = () => {
|
2023-11-21 01:29:46 -05:00
|
|
|
Hyprland.workspaces.forEach((ws) => {
|
2024-01-13 11:15:08 -05:00
|
|
|
const currentWs = (self.children as Array<AgsBox>)
|
|
|
|
.find((ch) => ch.attribute.id === ws.id);
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-20 03:45:05 -05:00
|
|
|
if (!currentWs && ws.id > 0) {
|
|
|
|
self.add(Workspace({ id: ws.id }));
|
2023-11-21 01:29:46 -05:00
|
|
|
}
|
2023-10-31 10:18:58 -04:00
|
|
|
});
|
|
|
|
self.show_all();
|
2023-09-20 20:25:52 -04:00
|
|
|
|
2023-10-31 10:18:58 -04:00
|
|
|
// Make sure the order is correct
|
2023-12-20 03:45:05 -05:00
|
|
|
workspaces().forEach((workspace, i) => {
|
2024-01-13 11:15:08 -05:00
|
|
|
(<AgsBox> workspace.get_parent()).reorder_child(
|
2023-12-20 03:45:05 -05:00
|
|
|
workspace,
|
|
|
|
i,
|
|
|
|
);
|
|
|
|
});
|
2023-12-18 18:00:30 -05:00
|
|
|
};
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
self.hook(Hyprland, () => {
|
2023-12-18 18:00:30 -05:00
|
|
|
self.attribute.workspaces =
|
2024-01-13 11:15:08 -05:00
|
|
|
(self.children as Array<AgsBox>).filter((ch) => {
|
2023-12-18 18:00:30 -05:00
|
|
|
return Hyprland.workspaces.find((ws) => {
|
2023-12-20 03:45:05 -05:00
|
|
|
return ws.id === ch.attribute.id;
|
2023-12-18 18:00:30 -05:00
|
|
|
});
|
|
|
|
}).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();
|
2023-10-31 10:18:58 -04:00
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
// Make sure the highlight doesn't go too far
|
|
|
|
const TEMP_TIMEOUT = 10;
|
2023-11-21 01:29:46 -05:00
|
|
|
|
2023-12-17 00:01:58 -05:00
|
|
|
timeout(TEMP_TIMEOUT, () => updateHighlight(highlight));
|
|
|
|
});
|
|
|
|
},
|
2023-10-31 10:18:58 -04:00
|
|
|
}),
|
2023-10-20 23:11:21 -04:00
|
|
|
}),
|
2023-10-31 10:18:58 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
return widget;
|
|
|
|
};
|