import options from 'options'; import brightness from 'services/Brightness'; import { OSDLabel } from './label/index'; import { OSDBar } from './bar/index'; import { OSDIcon } from './icon/index'; import { getPosition } from 'lib/utils'; import { Attribute, Child } from 'lib/types/widget'; import { Revealer } from 'resource:///com/github/Aylur/ags/widgets/revealer.js'; import { Window } from 'resource:///com/github/Aylur/ags/widgets/window.js'; const hyprland = await Service.import('hyprland'); const audio = await Service.import('audio'); const { enable, duration, orientation, location, active_monitor, monitor } = options.theme.osd; const curMonitor = Variable(monitor.value); hyprland.active.connect('changed', () => { curMonitor.value = hyprland.active.monitor.id; }); let count = 0; const handleRevealRevealer = (self: Revealer, property: 'reveal_child' | 'visible'): void => { if (!enable.value || property !== 'reveal_child') { return; } self.reveal_child = true; count++; Utils.timeout(duration.value, () => { count--; if (count === 0) { self.reveal_child = false; } }); }; const handleRevealWindow = (self: Window, property: 'reveal_child' | 'visible'): void => { if (!enable.value || property !== 'visible') { return; } self.visible = true; count++; Utils.timeout(duration.value, () => { count--; if (count === 0) { self.visible = false; } }); }; const handleReveal = ( self: Revealer | Window, property: 'reveal_child' | 'visible', ): void => { if (self instanceof Revealer) { handleRevealRevealer(self, property); } else if (self instanceof Window) { handleRevealWindow(self, property); } }; const renderOSD = (): Revealer => { return Widget.Revealer({ transition: 'crossfade', reveal_child: false, setup: (self) => { self.hook( brightness, () => { handleReveal(self, 'reveal_child'); }, 'notify::screen', ); self.hook( brightness, () => { handleReveal(self, 'reveal_child'); }, 'notify::kbd', ); self.hook( audio.microphone, () => { handleReveal(self, 'reveal_child'); }, 'notify::volume', ); self.hook( audio.microphone, () => { handleReveal(self, 'reveal_child'); }, 'notify::is-muted', ); self.hook( audio.speaker, () => { handleReveal(self, 'reveal_child'); }, 'notify::volume', ); self.hook( audio.speaker, () => { handleReveal(self, 'reveal_child'); }, 'notify::is-muted', ); }, child: Widget.Box({ class_name: 'osd-container', vertical: orientation.bind('value').as((ort) => ort === 'vertical'), children: orientation.bind('value').as((ort) => { if (ort === 'vertical') { return [OSDLabel(), OSDBar(ort), OSDIcon()]; } return [OSDIcon(), OSDBar(ort), OSDLabel()]; }), }), }); }; export default (): Window => Widget.Window({ monitor: Utils.merge( [curMonitor.bind('value'), monitor.bind('value'), active_monitor.bind('value')], (curMon, mon, activeMonitor) => { if (activeMonitor === true) { return curMon; } return mon; }, ), name: `indicator`, class_name: 'indicator', layer: options.tear.bind('value').as((tear) => (tear ? 'top' : 'overlay')), anchor: location.bind('value').as((v) => getPosition(v)), click_through: true, child: Widget.Box({ css: 'padding: 1px;', expand: true, child: renderOSD(), }), setup: (self) => { self.hook(enable, () => { handleReveal(self, 'visible'); }); self.hook( brightness, () => { handleReveal(self, 'visible'); }, 'notify::screen', ); self.hook( brightness, () => { handleReveal(self, 'visible'); }, 'notify::kbd', ); self.hook( audio.microphone, () => { handleReveal(self, 'visible'); }, 'notify::volume', ); self.hook( audio.microphone, () => { handleReveal(self, 'visible'); }, 'notify::is-muted', ); self.hook( audio.speaker, () => { handleReveal(self, 'visible'); }, 'notify::volume', ); self.hook( audio.speaker, () => { handleReveal(self, 'visible'); }, 'notify::is-muted', ); }, });