From 0ce1b486313b044c9bace57a63bb1fe70fb14c12 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Thu, 21 Mar 2024 21:45:07 -0400 Subject: [PATCH] refactor(ags): remake fullscreen bar hiding from scratch --- modules/ags/config/services/pointers.ts | 8 +- modules/ags/config/ts/bar/binto.ts | 16 +-- modules/ags/config/ts/bar/fullscreen.ts | 167 ++++++++++++++---------- modules/ags/config/ts/bar/wim.ts | 79 ++++++----- 4 files changed, 151 insertions(+), 119 deletions(-) diff --git a/modules/ags/config/services/pointers.ts b/modules/ags/config/services/pointers.ts index 64c3a80..4c42230 100644 --- a/modules/ags/config/services/pointers.ts +++ b/modules/ags/config/services/pointers.ts @@ -155,7 +155,13 @@ class Pointers extends Service { const overlayLayer = key.levels['3']; if (overlayLayer) { - const noCloseWidgetsNames = ['bar', 'osk']; + const noCloseWidgetsNames = [ + 'bar-0', + 'bar-1', + 'bar-2', + 'bar-3', + 'osk', + ]; const getNoCloseWidgets = (names: Array) => { const arr = [] as Array; diff --git a/modules/ags/config/ts/bar/binto.ts b/modules/ags/config/ts/bar/binto.ts index df62420..970e8a3 100644 --- a/modules/ags/config/ts/bar/binto.ts +++ b/modules/ags/config/ts/bar/binto.ts @@ -1,7 +1,9 @@ -const { Box, CenterBox, Window } = Widget; +const { Box, CenterBox } = Widget; import Separator from '../misc/separator.ts'; +import BarRevealer from './fullscreen.ts'; + import Clock from './items/clock.ts'; import NotifButton from './items/notif-button.ts'; import RazerStats from './items/razer-stats.ts'; @@ -9,19 +11,17 @@ import SysTray from './items/systray.ts'; const PADDING = 20; - -export default () => Window({ - name: 'bar', - layer: 'overlay', +export default () => BarRevealer({ + monitor: 1, exclusivity: 'exclusive', anchor: ['bottom', 'left', 'right'], - monitor: 1, - - child: Box({ + bar: Box({ vertical: true, children: [ CenterBox({ class_name: 'bar', + hexpand: true, + start_widget: Box({ hpack: 'start', children: [ diff --git a/modules/ags/config/ts/bar/fullscreen.ts b/modules/ags/config/ts/bar/fullscreen.ts index 6faef7d..8e24386 100644 --- a/modules/ags/config/ts/bar/fullscreen.ts +++ b/modules/ags/config/ts/bar/fullscreen.ts @@ -1,86 +1,117 @@ const Hyprland = await Service.import('hyprland'); - const { Box, EventBox, Revealer, Window } = Widget; -// Types -import { Variable as Var } from 'types/variable'; -import { BoxGeneric, DefaultProps } from 'global-types'; - -const BarCloser = (variable: Var) => Window({ - name: 'bar-closer', - visible: false, - anchor: ['top', 'bottom', 'left', 'right'], - layer: 'overlay', - - child: EventBox({ - on_hover: (self) => { - variable.setValue(false); - const parent = self.get_parent(); - - if (parent) { - parent.visible = false; - } - }, - - child: Box({ - css: 'padding: 1px', - }), - }), +const FullscreenState = Variable({ + fullscreen: false, + monitors: [] as number[], + clientAddrs: new Map() as Map, }); -export default (props?: DefaultProps) => { - const Revealed = Variable(true); - const barCloser = BarCloser(Revealed); +Hyprland.connect('event', (hyprObj) => { + const arrayEquals = (a1: unknown[], a2: unknown[]) => + a1.sort().toString() === a2.sort().toString(); + const mapEquals = (m1: Map, m2: Map) => + m1.size === m2.size && + Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key)); - return Box({ - css: 'min-height: 1px', - hexpand: true, - vertical: true, + const fs = FullscreenState.value; + const fsClients = hyprObj.clients.filter((c) => c.fullscreen); - setup: (self) => { - const checkCurrentWsFsState = () => { - const workspace = Hyprland.getWorkspace( - Hyprland.active.workspace.id, - ); + const fullscreen = fsClients.length > 0; + const monitors = fsClients.map((c) => c.monitor); + const clientAddrs = new Map(fsClients.map((c) => [c.monitor, c.address])); - if (workspace) { - Revealed.setValue(!workspace['hasfullscreen']); - } - }; + const hasChanged = fullscreen !== fs.fullscreen || + !arrayEquals(monitors, fs.monitors) || + !mapEquals(clientAddrs, fs.clientAddrs); - const checkGlobalFsState = (_: BoxGeneric, fullscreen: boolean) => { - Revealed.setValue(!fullscreen); - }; + if (hasChanged) { + FullscreenState.setValue({ + fullscreen, + monitors, + clientAddrs, + }); + } +}); - self - .hook(Hyprland.active, checkCurrentWsFsState) - .hook(Hyprland, checkGlobalFsState, 'fullscreen'); +export default ({ bar, monitor = 0, ...rest }) => { + const BarVisible = Variable(true); + + FullscreenState.connect('changed', (v) => { + BarVisible.setValue(!v.value.monitors.includes(monitor)); + }); + + // Hide bar instantly when out of focus + Hyprland.active.workspace.connect('changed', () => { + const addr = FullscreenState.value.clientAddrs.get(monitor); + + if (addr) { + const client = Hyprland.getClient(addr); + + if (client!.workspace.id !== Hyprland.active.workspace.id) { + BarVisible.setValue(false); + } + } + }); + + const barCloser = Window({ + name: `bar-${monitor}-closer`, + visible: false, + monitor, + anchor: ['top', 'bottom', 'left', 'right'], + layer: 'overlay', + + child: EventBox({ + on_hover: (self) => { + const parent = self.get_parent(); + + parent?.set_visible(false); + BarVisible.setValue(false); + }, + + child: Box({ + css: 'padding: 1px;', + }), + }), + }); + + return Window({ + name: `bar-${monitor}`, + layer: 'overlay', + monitor, + margins: [-1, -1, -1, -1], + ...rest, + + attribute: { + barCloser, }, - children: [ - Revealer({ - ...props, - transition: 'slide_down', - reveal_child: true, + child: EventBox({ + child: Box({ + css: 'min-height: 1px; padding: 1px;', + hexpand: true, + hpack: 'fill', + vertical: true, - }).bind('reveal_child', Revealed), - - Revealer({ - reveal_child: Revealed.bind() - .transform((v) => !v), - - child: EventBox({ - on_hover: () => { - barCloser.visible = true; - Revealed.setValue(true); - }, - - child: Box({ - css: 'min-height: 5px;', + children: [ + Box({ + css: 'min-height: 10px', + visible: BarVisible.bind().as((v) => !v), }), - }), + + Revealer({ + transition: 'slide_up', + reveal_child: BarVisible.bind(), + child: bar, + }), + ], }), - ], + }).on('enter-notify-event', () => { + if (!BarVisible.value) { + barCloser.visible = true; + BarVisible.setValue(true); + } + }), }); }; diff --git a/modules/ags/config/ts/bar/wim.ts b/modules/ags/config/ts/bar/wim.ts index f1b81f5..7c188a0 100644 --- a/modules/ags/config/ts/bar/wim.ts +++ b/modules/ags/config/ts/bar/wim.ts @@ -1,4 +1,4 @@ -const { Window, CenterBox, Box } = Widget; +const { CenterBox, Box } = Widget; import Separator from '../misc/separator.ts'; @@ -13,73 +13,68 @@ import SysTray from './items/systray.ts'; import TabletToggle from './items/tablet-toggle.ts'; import Workspaces from './items/workspaces.ts'; -import BarReveal from './fullscreen.ts'; +import BarRevealer from './fullscreen.ts'; const SPACING = 12; -export default () => Window({ - name: 'bar', - layer: 'overlay', +export default () => BarRevealer({ anchor: ['top', 'left', 'right'], - margins: [-1, 0, 0, 0], exclusivity: 'exclusive', - child: BarReveal({ - child: CenterBox({ - css: 'margin: 6px 5px 5px 5px', - class_name: 'bar', + bar: CenterBox({ + css: 'margin: 5px 5px 5px 5px', + class_name: 'bar', - start_widget: Box({ - hpack: 'start', - children: [ + start_widget: Box({ + hpack: 'start', + children: [ - OskToggle(), + OskToggle(), - Separator(SPACING), + Separator(SPACING), - TabletToggle(), + TabletToggle(), - Separator(SPACING), + Separator(SPACING), - SysTray(), + SysTray(), - Workspaces(), + Workspaces(), - Separator(SPACING), + Separator(SPACING), - CurrentWindow(), + CurrentWindow(), - ], - }), + ], + }), - center_widget: Box({ - children: [ - Separator(SPACING), + center_widget: Box({ + children: [ + Separator(SPACING), - Clock(), + Clock(), - Separator(SPACING), - ], - }), + Separator(SPACING), + ], + }), - end_widget: Box({ - hpack: 'end', - children: [ - Heart(), + end_widget: Box({ + hpack: 'end', + children: [ + Heart(), - Separator(SPACING), + Separator(SPACING), - Battery(), + Battery(), - Separator(SPACING), + Separator(SPACING), - NotifButton(), + NotifButton(), - Separator(SPACING), + Separator(SPACING), - QsToggle(), - ], - }), + QsToggle(), + ], }), }), });