diff options
| author | srdusr <trevorgray@srdusr.com> | 2024-06-13 13:11:05 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2024-06-13 13:11:05 +0200 |
| commit | d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e (patch) | |
| tree | 937531ddf423d3935c6e20c8a9227e39ce782241 /.config/ags/widget/dock/Dock.ts | |
| parent | 4ccbe0270c25ecab492508b5b0209ae53b9c35bd (diff) | |
| download | dotfiles-d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e.tar.gz dotfiles-d0fbb19623e4fb6097e1ff3ee49c6a76a0928d0e.zip | |
Add ags
Diffstat (limited to '.config/ags/widget/dock/Dock.ts')
| -rw-r--r-- | .config/ags/widget/dock/Dock.ts | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/.config/ags/widget/dock/Dock.ts b/.config/ags/widget/dock/Dock.ts new file mode 100644 index 0000000..c55f89f --- /dev/null +++ b/.config/ags/widget/dock/Dock.ts @@ -0,0 +1,150 @@ +import { launchApp } from "lib/utils"; +import options from "options"; +import * as Gtk from "gi://Gtk?version=3.0"; +import { type ButtonProps } from "types/widgets/button"; +import { type BoxProps } from "types/widgets/box"; + +const hyprland = await Service.import("hyprland"); +const applications = await Service.import("applications"); + +const focus = (address: string) => hyprland.messageAsync(`dispatch focuswindow address:${address}`); + +const AppButton = ({ icon, pinned = false, term, ...rest }: ButtonProps & { term?: string }): Gtk.Button & ButtonProps => { + const { iconSize } = options.dock; + + const buttonBox = Widget.Box({ + class_name: 'box', + child: Widget.Icon({ + icon, + size: iconSize, + }), + }); + + const button = Widget.Button({ + ...rest, + class_name: '', + child: pinned ? buttonBox : Widget.Overlay({ + child: buttonBox, + pass_through: false, + overlays: [], + }), + }); + + return Object.assign(button, {}); +}; + +const createAppButton = ({ app, term, ...params }) => { + return AppButton({ + icon: app.icon_name || '', + term, + ...params, + }); +}; + +const filterValidClients = (clients: any[]) => { + return clients.filter(client => ( + client.mapped && + [client.class, client.title, client.initialClass].every(prop => typeof prop === 'string' && prop !== '') + )); +}; + +const Taskbar = (): Gtk.Box & BoxProps => { + const addedApps = new Set<string>(); + + const updateTaskbar = (clients: any[]) => { + const validClients = filterValidClients(clients); + + const focusedAddress = hyprland?.active.client?.address; + const running = validClients.filter(client => client.mapped); + const focused = running.find(client => client.address === focusedAddress); + + return validClients.map(client => { + if (![client.class, client.title, client.initialClass].every(prop => typeof prop === 'string' && prop !== '')) { + return null; + } + + if (addedApps.has(client.title)) { + return null; + } + + for (const appName of options.dock.pinnedApps.value) { + if (!appName || typeof appName !== 'string') { + continue; + } + + if (client.class.includes(appName) || client.title.includes(appName) + || client.initialClass.includes(appName)) { + return null; + } + } + + const matchingApp = applications?.list.find(app => ( + app.match(client.title) || app.match(client.class) || app.match(client.initialClass) + )); + + if (matchingApp) { + addedApps.add(client.title); + return createAppButton({ + app: matchingApp, + term: matchingApp.title, + on_primary_click: () => { + const clickAddress = client.address || focusedAddress; + clickAddress && focus(clickAddress); + }, + on_secondary_click: () => launchApp(matchingApp), + }); + a + } + return null; + }); + }; + + return Widget.Box({ + vertical: false, + }) + .bind('children', hyprland, 'clients', updateTaskbar); +}; + +const PinnedApps = (): Gtk.Box & BoxProps => { + const updatePinnedApps = (pinnedApps: string[]) => { + return pinnedApps + .map(term => ({ app: applications?.query(term)?.[0], term })) + .filter(({ app }) => app) + .map(({ app, term = true }) => createAppButton({ + app, + term, + pinned: true, + on_primary_click: () => { + const matchingClients = hyprland?.clients.filter(client => ( + typeof client.class === 'string' && + typeof client.title === 'string' && + typeof client.initialClass === 'string' && + (client.class.includes(term) || client.title.includes(term) || client.initialClass.includes(term)) + )); + + if (matchingClients.length > 0) { + const { address } = matchingClients[0]; + address && focus(address); + } else { + launchApp(app); + } + }, + on_secondary_click: () => launchApp(app), + })); + }; + + return Widget.Box({ + class_name: 'pins', + vertical: false, + homogeneous: true, + }) + .bind('children', options.dock.pinnedApps, 'value', updatePinnedApps); +}; + +const Dock = (): Gtk.Box & BoxProps => Widget.Box({ + class_name: 'dock', + vertical: false, + children: [PinnedApps(), Taskbar()], +}); + +export default Dock; |
