diff options
Diffstat (limited to '.config/ags/widget/bar/buttons')
| -rw-r--r-- | .config/ags/widget/bar/buttons/BatteryBar.ts | 94 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/ColorPicker.ts | 37 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Date.ts | 15 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Launcher.ts | 49 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Media.ts | 92 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Messages.ts | 16 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/PowerMenu.ts | 15 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/ScreenRecord.ts | 21 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/SysTray.ts | 39 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/SystemIndicators.ts | 107 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Taskbar.ts | 90 | ||||
| -rw-r--r-- | .config/ags/widget/bar/buttons/Workspaces.ts | 66 |
12 files changed, 0 insertions, 641 deletions
diff --git a/.config/ags/widget/bar/buttons/BatteryBar.ts b/.config/ags/widget/bar/buttons/BatteryBar.ts deleted file mode 100644 index 18de329..0000000 --- a/.config/ags/widget/bar/buttons/BatteryBar.ts +++ /dev/null @@ -1,94 +0,0 @@ -import icons from "lib/icons" -import options from "options" -import PanelButton from "../PanelButton" - -const battery = await Service.import("battery") -const { bar, percentage, blocks, width, low } = options.bar.battery - -const Indicator = () => Widget.Icon({ - setup: self => self.hook(battery, () => { - self.icon = battery.charging || battery.charged - ? icons.battery.charging - : battery.icon_name - }), -}) - -const PercentLabel = () => Widget.Revealer({ - transition: "slide_right", - click_through: true, - reveal_child: percentage.bind(), - child: Widget.Label({ - label: battery.bind("percent").as(p => `${p}%`), - }), -}) - -const LevelBar = () => { - const level = Widget.LevelBar({ - bar_mode: "discrete", - max_value: blocks.bind(), - visible: bar.bind().as(b => b !== "hidden"), - value: battery.bind("percent").as(p => (p / 100) * blocks.value), - }) - const update = () => { - level.value = (battery.percent / 100) * blocks.value - level.css = `block { min-width: ${width.value / blocks.value}pt; }` - } - return level - .hook(width, update) - .hook(blocks, update) - .hook(bar, () => { - level.vpack = bar.value === "whole" ? "fill" : "center" - level.hpack = bar.value === "whole" ? "fill" : "center" - }) -} - -const WholeButton = () => Widget.Overlay({ - vexpand: true, - child: LevelBar(), - class_name: "whole", - pass_through: true, - overlay: Widget.Box({ - hpack: "center", - children: [ - Widget.Icon({ - icon: icons.battery.charging, - visible: Utils.merge([ - battery.bind("charging"), - battery.bind("charged"), - ], (ing, ed) => ing || ed), - }), - Widget.Box({ - hpack: "center", - vpack: "center", - child: PercentLabel(), - }), - ], - }), -}) - -const Regular = () => Widget.Box({ - class_name: "regular", - children: [ - Indicator(), - PercentLabel(), - LevelBar(), - ], -}) - -export default () => PanelButton({ - class_name: "battery-bar", - hexpand: false, - on_clicked: () => { percentage.value = !percentage.value }, - visible: battery.bind("available"), - child: Widget.Box({ - expand: true, - visible: battery.bind("available"), - child: bar.bind().as(b => b === "whole" ? WholeButton() : Regular()), - }), - setup: self => self - .hook(bar, w => w.toggleClassName("bar-hidden", bar.value === "hidden")) - .hook(battery, w => { - w.toggleClassName("charging", battery.charging || battery.charged) - w.toggleClassName("low", battery.percent < low.value) - }), -}) diff --git a/.config/ags/widget/bar/buttons/ColorPicker.ts b/.config/ags/widget/bar/buttons/ColorPicker.ts deleted file mode 100644 index 5b1f3f6..0000000 --- a/.config/ags/widget/bar/buttons/ColorPicker.ts +++ /dev/null @@ -1,37 +0,0 @@ -import PanelButton from "../PanelButton" -import colorpicker from "service/colorpicker" -import Gdk from "gi://Gdk" - -const css = (color: string) => ` -* { - background-color: ${color}; - color: transparent; -} -*:hover { - color: white; - text-shadow: 2px 2px 3px rgba(0,0,0,.8); -}` - -export default () => { - const menu = Widget.Menu({ - class_name: "colorpicker", - children: colorpicker.bind("colors").as(c => c.map(color => Widget.MenuItem({ - child: Widget.Label(color), - css: css(color), - on_activate: () => colorpicker.wlCopy(color), - }))), - }) - - return PanelButton({ - class_name: "color-picker", - child: Widget.Icon("color-select-symbolic"), - tooltip_text: colorpicker.bind("colors").as(v => `${v.length} colors`), - on_clicked: colorpicker.pick, - on_secondary_click: self => { - if (colorpicker.colors.length === 0) - return - - menu.popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null) - }, - }) -} diff --git a/.config/ags/widget/bar/buttons/Date.ts b/.config/ags/widget/bar/buttons/Date.ts deleted file mode 100644 index 44c2540..0000000 --- a/.config/ags/widget/bar/buttons/Date.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { clock } from "lib/variables" -import PanelButton from "../PanelButton" -import options from "options" - -const { format, action } = options.bar.date -const time = Utils.derive([clock, format], (c, f) => c.format(f) || "") - -export default () => PanelButton({ - window: "datemenu", - on_clicked: action.bind(), - child: Widget.Label({ - justification: "center", - label: time.bind(), - }), -}) diff --git a/.config/ags/widget/bar/buttons/Launcher.ts b/.config/ags/widget/bar/buttons/Launcher.ts deleted file mode 100644 index f3fee6b..0000000 --- a/.config/ags/widget/bar/buttons/Launcher.ts +++ /dev/null @@ -1,49 +0,0 @@ -import PanelButton from "../PanelButton" -import options from "options" -import nix from "service/nix" - -const { icon, label, action } = options.bar.launcher - -function Spinner() { - const child = Widget.Icon({ - icon: icon.icon.bind(), - class_name: Utils.merge([ - icon.colored.bind(), - nix.bind("ready"), - ], (c, r) => `${c ? "colored" : ""} ${r ? "" : "spinning"}`), - css: ` - @keyframes spin { - to { -gtk-icon-transform: rotate(1turn); } - } - - image.spinning { - animation-name: spin; - animation-duration: 1s; - animation-timing-function: linear; - animation-iteration-count: infinite; - } - `, - }) - - return Widget.Revealer({ - transition: "slide_left", - child, - reveal_child: Utils.merge([ - icon.icon.bind(), - nix.bind("ready"), - ], (i, r) => Boolean(i || r)), - }) -} - -export default () => PanelButton({ - window: "launcher", - on_clicked: action.bind(), - child: Widget.Box([ - Spinner(), - Widget.Label({ - class_name: label.colored.bind().as(c => c ? "colored" : ""), - visible: label.label.bind().as(v => !!v), - label: label.label.bind(), - }), - ]), -}) diff --git a/.config/ags/widget/bar/buttons/Media.ts b/.config/ags/widget/bar/buttons/Media.ts deleted file mode 100644 index b3aab61..0000000 --- a/.config/ags/widget/bar/buttons/Media.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { type MprisPlayer } from "types/service/mpris" -import PanelButton from "../PanelButton" -import options from "options" -import icons from "lib/icons" -import { icon } from "lib/utils" - -const mpris = await Service.import("mpris") -const { length, direction, preferred, monochrome, format } = options.bar.media - -const getPlayer = (name = preferred.value) => - mpris.getPlayer(name) || mpris.players[0] || null - -const Content = (player: MprisPlayer) => { - const revealer = Widget.Revealer({ - click_through: true, - visible: length.bind().as(l => l > 0), - transition: direction.bind().as(d => `slide_${d}` as const), - setup: self => { - let current = "" - self.hook(player, () => { - if (current === player.track_title) - return - - current = player.track_title - self.reveal_child = true - Utils.timeout(3000, () => { - !self.is_destroyed && (self.reveal_child = false) - }) - }) - }, - child: Widget.Label({ - truncate: "end", - max_width_chars: length.bind().as(n => n > 0 ? n : -1), - label: Utils.merge([ - player.bind("track_title"), - player.bind("track_artists"), - format.bind(), - ], () => `${format}` - .replace("{title}", player.track_title) - .replace("{artists}", player.track_artists.join(", ")) - .replace("{artist}", player.track_artists[0] || "") - .replace("{album}", player.track_album) - .replace("{name}", player.name) - .replace("{identity}", player.identity), - ), - }), - }) - - const playericon = Widget.Icon({ - icon: Utils.merge([player.bind("entry"), monochrome.bind()], (entry => { - const name = `${entry}${monochrome.value ? "-symbolic" : ""}` - return icon(name, icons.fallback.audio) - })), - }) - - return Widget.Box({ - attribute: { revealer }, - children: direction.bind().as(d => d === "right" - ? [playericon, revealer] : [revealer, playericon]), - }) -} - -export default () => { - let player = getPlayer() - - const btn = PanelButton({ - class_name: "media", - child: Widget.Icon(icons.fallback.audio), - }) - - const update = () => { - player = getPlayer() - btn.visible = !!player - - if (!player) - return - - const content = Content(player) - const { revealer } = content.attribute - btn.child = content - btn.on_primary_click = () => { player.playPause() } - btn.on_secondary_click = () => { player.playPause() } - btn.on_scroll_up = () => { player.next() } - btn.on_scroll_down = () => { player.previous() } - btn.on_hover = () => { revealer.reveal_child = true } - btn.on_hover_lost = () => { revealer.reveal_child = false } - } - - return btn - .hook(preferred, update) - .hook(mpris, update, "notify::players") -} diff --git a/.config/ags/widget/bar/buttons/Messages.ts b/.config/ags/widget/bar/buttons/Messages.ts deleted file mode 100644 index a8971e9..0000000 --- a/.config/ags/widget/bar/buttons/Messages.ts +++ /dev/null @@ -1,16 +0,0 @@ -import icons from "lib/icons" -import PanelButton from "../PanelButton" -import options from "options" - -const n = await Service.import("notifications") -const notifs = n.bind("notifications") -const action = options.bar.messages.action.bind() - -export default () => PanelButton({ - class_name: "messages", - on_clicked: action, - visible: notifs.as(n => n.length > 0), - child: Widget.Box([ - Widget.Icon(icons.notifications.message), - ]), -}) diff --git a/.config/ags/widget/bar/buttons/PowerMenu.ts b/.config/ags/widget/bar/buttons/PowerMenu.ts deleted file mode 100644 index 4432ade..0000000 --- a/.config/ags/widget/bar/buttons/PowerMenu.ts +++ /dev/null @@ -1,15 +0,0 @@ -import icons from "lib/icons" -import PanelButton from "../PanelButton" -import options from "options" - -const { monochrome, action } = options.bar.powermenu - -export default () => PanelButton({ - window: "powermenu", - on_clicked: action.bind(), - child: Widget.Icon(icons.powermenu.shutdown), - setup: self => self.hook(monochrome, () => { - self.toggleClassName("colored", !monochrome.value) - self.toggleClassName("box") - }), -}) diff --git a/.config/ags/widget/bar/buttons/ScreenRecord.ts b/.config/ags/widget/bar/buttons/ScreenRecord.ts deleted file mode 100644 index 1d6eb36..0000000 --- a/.config/ags/widget/bar/buttons/ScreenRecord.ts +++ /dev/null @@ -1,21 +0,0 @@ -import PanelButton from "../PanelButton" -import screenrecord from "service/screenrecord" -import icons from "lib/icons" - -export default () => PanelButton({ - class_name: "recorder", - on_clicked: () => screenrecord.stop(), - visible: screenrecord.bind("recording"), - child: Widget.Box({ - children: [ - Widget.Icon(icons.recorder.recording), - Widget.Label({ - label: screenrecord.bind("timer").as(time => { - const sec = time % 60 - const min = Math.floor(time / 60) - return `${min}:${sec < 10 ? "0" + sec : sec}` - }), - }), - ], - }), -}) diff --git a/.config/ags/widget/bar/buttons/SysTray.ts b/.config/ags/widget/bar/buttons/SysTray.ts deleted file mode 100644 index 9f569d1..0000000 --- a/.config/ags/widget/bar/buttons/SysTray.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { type TrayItem } from "types/service/systemtray" -import PanelButton from "../PanelButton" -import Gdk from "gi://Gdk" -import options from "options" - -const systemtray = await Service.import("systemtray") -const { ignore } = options.bar.systray - -const SysTrayItem = (item: TrayItem) => PanelButton({ - class_name: "tray-item", - child: Widget.Icon({ icon: item.bind("icon") }), - tooltip_markup: item.bind("tooltip_markup"), - setup: self => { - const { menu } = item - if (!menu) - return - - const id = menu.connect("popped-up", () => { - self.toggleClassName("active") - menu.connect("notify::visible", () => { - self.toggleClassName("active", menu.visible) - }) - menu.disconnect(id!) - }) - - self.connect("destroy", () => menu.disconnect(id)) - }, - - on_primary_click: btn => item.menu?.popup_at_widget( - btn, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null), - - on_secondary_click: btn => item.menu?.popup_at_widget( - btn, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null), -}) - -export default () => Widget.Box() - .bind("children", systemtray, "items", i => i - .filter(({ id }) => !ignore.value.includes(id)) - .map(SysTrayItem)) diff --git a/.config/ags/widget/bar/buttons/SystemIndicators.ts b/.config/ags/widget/bar/buttons/SystemIndicators.ts deleted file mode 100644 index cc98548..0000000 --- a/.config/ags/widget/bar/buttons/SystemIndicators.ts +++ /dev/null @@ -1,107 +0,0 @@ -import PanelButton from '../PanelButton'; -import icons from 'lib/icons'; -import asusctl from 'service/asusctl'; - -const notifications = await Service.import('notifications'); -const bluetooth = await Service.import('bluetooth'); -const audio = await Service.import('audio'); -const network = await Service.import('network'); -const powerprof = await Service.import('powerprofiles'); - -const ProfileIndicator = () => { - const visible = asusctl.available ? asusctl.bind('profile').as(p => p !== 'Balanced') : powerprof.bind('active_profile').as(p => p !== 'balanced'); - - const icon = asusctl.available ? asusctl.bind('profile').as(p => icons.asusctl.profile[p]) : powerprof.bind('active_profile').as(p => icons.powerprofile[p]); - - return Widget.Icon({ visible, icon }); -}; - -const ModeIndicator = () => { - if (!asusctl.available) { - return Widget.Icon({ - setup(self) { - Utils.idle(() => (self.visible = false)); - }, - }); - } - - return Widget.Icon({ - visible: asusctl.bind('mode').as(m => m !== 'Hybrid'), - icon: asusctl.bind('mode').as(m => icons.asusctl.mode[m]), - }); -}; - -const MicrophoneIndicator = () => - Widget.Icon() - .hook(audio, self => (self.visible = audio.recorders.length > 0 || audio.microphone.is_muted || false)) - .hook(audio.microphone, self => { - const vol = audio.microphone.is_muted ? 0 : audio.microphone.volume; - const { muted, low, medium, high } = icons.audio.mic; - const cons = [ - [67, high], - [34, medium], - [1, low], - [0, muted], - ] as const; - self.icon = cons.find(([n]) => n <= vol * 100)?.[1] || ''; - }); - -const DNDIndicator = () => - Widget.Icon({ - visible: notifications.bind('dnd'), - icon: icons.notifications.silent, - }); - -const BluetoothIndicator = () => - Widget.Overlay({ - class_name: 'bluetooth', - passThrough: true, - child: Widget.Icon({ - icon: icons.bluetooth.enabled, - visible: bluetooth.bind('enabled'), - }), - overlay: Widget.Label({ - hpack: 'end', - vpack: 'start', - label: bluetooth.bind('connected_devices').as(c => `${c.length}`), - visible: bluetooth.bind('connected_devices').as(c => c.length > 0), - }), - }); - -const NetworkIndicator = () => - Widget.Icon().hook(network, self => { - const icon = network[network.primary || 'wifi']?.icon_name; - self.icon = icon || ''; - self.visible = !!icon; - }); - -const AudioIndicator = () => - Widget.Icon().hook(audio.speaker, self => { - const vol = audio.speaker.is_muted ? 0 : audio.speaker.volume; - const { muted, low, medium, high, overamplified } = icons.audio.volume; - const cons = [ - [101, overamplified], - [67, high], - [34, medium], - [1, low], - [0, muted], - ] as const; - self.icon = cons.find(([n]) => n <= vol * 100)?.[1] || ''; - }); - -export default () => - PanelButton({ - window: 'quicksettings', - on_clicked: () => App.toggleWindow('quicksettings'), - on_scroll_up: () => (audio.speaker.volume += 0.02), - on_scroll_down: () => (audio.speaker.volume -= 0.02), - child: Widget.Box([ - //ProfileIndicator(), - ModeIndicator(), - DNDIndicator(), - BluetoothIndicator(), - MicrophoneIndicator(), - AudioIndicator(), - NetworkIndicator(), - ]), - }); diff --git a/.config/ags/widget/bar/buttons/Taskbar.ts b/.config/ags/widget/bar/buttons/Taskbar.ts deleted file mode 100644 index b9c65fa..0000000 --- a/.config/ags/widget/bar/buttons/Taskbar.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { launchApp, icon } from "lib/utils" -import icons from "lib/icons" -import options from "options" -import PanelButton from "../PanelButton" - -const hyprland = await Service.import("hyprland") -const apps = await Service.import("applications") -const { monochrome, exclusive, iconSize } = options.bar.taskbar -const { position } = options.bar - -const focus = (address: string) => hyprland.messageAsync( - `dispatch focuswindow address:${address}`) - -const DummyItem = (address: string) => Widget.Box({ - attribute: { address }, - visible: false, -}) - -const AppItem = (address: string) => { - const client = hyprland.getClient(address) - if (!client || client.class === "") - return DummyItem(address) - - const app = apps.list.find(app => app.match(client.class)) - - const btn = PanelButton({ - class_name: "panel-button", - tooltip_text: Utils.watch(client.title, hyprland, () => - hyprland.getClient(address)?.title || "", - ), - on_primary_click: () => focus(address), - on_middle_click: () => app && launchApp(app), - child: Widget.Icon({ - size: iconSize.bind(), - icon: monochrome.bind().as(m => icon( - (app?.icon_name || client.class) + (m ? "-symbolic" : ""), - icons.fallback.executable + (m ? "-symbolic" : ""), - )), - }), - }) - - return Widget.Box( - { - attribute: { address }, - visible: Utils.watch(true, [exclusive, hyprland], () => { - return exclusive.value - ? hyprland.active.workspace.id === client.workspace.id - : true - }), - }, - Widget.Overlay({ - child: btn, - pass_through: true, - overlay: Widget.Box({ - className: "indicator", - hpack: "center", - vpack: position.bind().as(p => p === "top" ? "start" : "end"), - setup: w => w.hook(hyprland, () => { - w.toggleClassName("active", hyprland.active.client.address === address) - }), - }), - }), - ) -} - -function sortItems<T extends { attribute: { address: string } }>(arr: T[]) { - return arr.sort(({ attribute: a }, { attribute: b }) => { - const aclient = hyprland.getClient(a.address)! - const bclient = hyprland.getClient(b.address)! - return aclient.workspace.id - bclient.workspace.id - }) -} - -export default () => Widget.Box({ - class_name: "taskbar", - children: sortItems(hyprland.clients.map(c => AppItem(c.address))), - setup: w => w - .hook(hyprland, (w, address?: string) => { - if (typeof address === "string") - w.children = w.children.filter(ch => ch.attribute.address !== address) - }, "client-removed") - .hook(hyprland, (w, address?: string) => { - if (typeof address === "string") - w.children = sortItems([...w.children, AppItem(address)]) - }, "client-added") - .hook(hyprland, (w, event?: string) => { - if (event === "movewindow") - w.children = sortItems(w.children) - }, "event"), -}) diff --git a/.config/ags/widget/bar/buttons/Workspaces.ts b/.config/ags/widget/bar/buttons/Workspaces.ts deleted file mode 100644 index a59f61b..0000000 --- a/.config/ags/widget/bar/buttons/Workspaces.ts +++ /dev/null @@ -1,66 +0,0 @@ -import PanelButton from '../PanelButton'; -import options from 'options'; -import { sh, range } from 'lib/utils'; - -const hyprland = await Service.import('hyprland'); -const { workspaces } = options.bar.workspaces; - -const dispatch = arg => { - sh(`hyprctl dispatch workspace ${arg}`); -}; - -const Workspaces = ws => - Widget.Box({ - children: range(ws || 20).map(i => - Widget.Label({ - attribute: i, - vpack: 'center', - label: `${i}`, - setup: self => { - const updateState = () => { - const monitorData = JSON.parse(hyprland.message('j/monitors')); - const activeWorkspaceId = monitorData[0]?.activeWorkspace?.id; - const workspaceData = hyprland.getWorkspace(i); - - if (activeWorkspaceId !== undefined) { - self.toggleClassName('active', activeWorkspaceId === i); - } - self.toggleClassName('occupied', (workspaceData?.windows || 0) > 0); - }; - - // Hook to Hyprland for updates - self.hook(hyprland, updateState); - - // Initial update - updateState(); - }, - }), - ), - setup: box => { - box.hook(hyprland, () => { - const monitorData = JSON.parse(hyprland.message('j/monitors')); - const activeWorkspaceId = monitorData[0]?.activeWorkspace?.id; - - if (activeWorkspaceId !== undefined) { - for (const btn of box.children) { - const workspaceId = btn.attribute; - btn.toggleClassName('active', workspaceId === activeWorkspaceId); - - if (ws === 0) { - btn.visible = hyprland.workspaces.some(workspace => workspace.id === workspaceId); - } - } - } - }); - }, - }); - -export default () => - PanelButton({ - window: 'overview', - class_name: 'workspaces', - on_scroll_up: () => dispatch('m+1'), - on_scroll_down: () => dispatch('m-1'), - on_clicked: () => App.toggleWindow('overview'), - child: workspaces.bind().as(Workspaces), - }); |
