From a4fd6091b4862048a3580756403a6ceb42e4a835 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Mon, 4 Sep 2023 00:41:14 -0400 Subject: [PATCH] feat(ags): add workspace widget WIP --- config/ags/style.scss | 1 + config/ags/traybuttons/traybuttons.js | 7 ++- config/ags/workspaces/workspaces.js | 70 +++++++++++++++++++++++++++ config/ags/workspaces/workspaces.scss | 27 +++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 config/ags/workspaces/workspaces.js create mode 100644 config/ags/workspaces/workspaces.scss diff --git a/config/ags/style.scss b/config/ags/style.scss index 3c83caf..22ca53c 100644 --- a/config/ags/style.scss +++ b/config/ags/style.scss @@ -5,3 +5,4 @@ @import "/home/matt/.nix/config/ags/colors.scss"; @import "/home/matt/.nix/config/ags/powermenu/powermenu.scss"; @import "/home/matt/.nix/config/ags/traybuttons/traybuttons.scss"; +@import "/home/matt/.nix/config/ags/workspaces/workspaces.scss"; diff --git a/config/ags/traybuttons/traybuttons.js b/config/ags/traybuttons/traybuttons.js index 6e7ef42..bb2135a 100644 --- a/config/ags/traybuttons/traybuttons.js +++ b/config/ags/traybuttons/traybuttons.js @@ -1,9 +1,10 @@ import Gdk from 'gi://Gdk'; const display = Gdk.Display.get_default(); import { CurrentWindow } from 'file:///home/matt/.nix/config/ags/current-window/current-window.js'; +import { Workspaces } from 'file:///home/matt/.nix/config/ags/workspaces/workspaces.js'; const Separator = () => ags.Widget.Box({ - style: 'min-width: 8px; min-height: 8px', + style: 'min-width: 12px;', }); ags.Utils.subprocess( @@ -127,6 +128,10 @@ export const LeftBar = ags.Widget.Window({ HeartToggle, + Separator(), + + Workspaces(), + ], }), diff --git a/config/ags/workspaces/workspaces.js b/config/ags/workspaces/workspaces.js new file mode 100644 index 0000000..7f769c7 --- /dev/null +++ b/config/ags/workspaces/workspaces.js @@ -0,0 +1,70 @@ +// https://github.com/Aylur/dotfiles/blob/f03e58ba0d3b56f1144631c179ab27357e466753/.config/ags/modules/hyprland.js#L4 +import Gdk from 'gi://Gdk'; +const display = Gdk.Display.get_default(); +const { App } = ags; +const { Hyprland, Applications } = ags.Service; +const { execAsync, lookUpIcon } = ags.Utils; +const { Box, Button, EventBox, Label, Icon } = ags.Widget; + +export const Workspace = ({ i, } = {}) => +EventBox({ + onPrimaryClickRelease: () => execAsync(`hyprctl dispatch workspace ${i}`).catch(print), + onHover: box => { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer')); + }, + onHoverLost: box => { + box.window.set_cursor(null); + }, + child: Box({ + className: 'button', + child: Label(`${i}`), + connections: [ + [Hyprland, btn => { + const { workspaces, active } = Hyprland; + const occupied = workspaces.has(i) && workspaces.get(i).windows > 0; + btn.toggleClassName('active', active.workspace.id === i); + btn.toggleClassName('occupied', occupied); + btn.toggleClassName('empty', !occupied); + }] + ], + }), +}); + +var prev = Hyprland.active.workspace.id; + +export const Workspaces = props => Box({ + className: 'workspaces panel-button', + children: [EventBox({ + child: Box({ + connections: [[Hyprland, box => { + let workspaces = []; + + new Promise(resolve => { + + Hyprland.workspaces.forEach(ws => { + if (ws.id > 0) { + workspaces.push(ws); + } + }); + + resolve(); + }).then(value => { + + if (workspaces.length > 0) { + let currentId = Hyprland.active.workspace.id; + let qtyChange = Number(currentId - box.children.length); + + if (qtyChange != 0 && currentId != prev) { + box.get_children().forEach(ch => ch.destroy()); + box.children = Array.from( + { length: Math.max(...workspaces.map(ws => ws.id)) }, + (_, i) => i + 1).map(i => Workspace({ i: i})); + } + prev = currentId; + } + + }); + }]], + }), + })], +}); diff --git a/config/ags/workspaces/workspaces.scss b/config/ags/workspaces/workspaces.scss new file mode 100644 index 0000000..b235137 --- /dev/null +++ b/config/ags/workspaces/workspaces.scss @@ -0,0 +1,27 @@ +.workspaces { + background-color: $bg; + border-radius: 80px; + border: 2px solid #1b1b1b; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 12px; + padding-right: 12px; + + .button { + margin: 2px; + min-width: 20px; + border-radius: 100%; + * {color: transparent;} + } + + .empty { + border: none; + } + .occupied { + border: 2px solid $bg; + background: $contrastbg; + } + .active { + border: 2px solid #50fa7b; + } +}