refactor(ags): remake fullscreen bar hiding from scratch
All checks were successful
Discord / discord commits (push) Has been skipped

This commit is contained in:
matt1432 2024-03-21 21:45:07 -04:00
parent 66a6a7a417
commit 0ce1b48631
4 changed files with 151 additions and 119 deletions

View file

@ -155,7 +155,13 @@ class Pointers extends Service {
const overlayLayer = key.levels['3']; const overlayLayer = key.levels['3'];
if (overlayLayer) { if (overlayLayer) {
const noCloseWidgetsNames = ['bar', 'osk']; const noCloseWidgetsNames = [
'bar-0',
'bar-1',
'bar-2',
'bar-3',
'osk',
];
const getNoCloseWidgets = (names: Array<string>) => { const getNoCloseWidgets = (names: Array<string>) => {
const arr = [] as Array<Layer>; const arr = [] as Array<Layer>;

View file

@ -1,7 +1,9 @@
const { Box, CenterBox, Window } = Widget; const { Box, CenterBox } = Widget;
import Separator from '../misc/separator.ts'; import Separator from '../misc/separator.ts';
import BarRevealer from './fullscreen.ts';
import Clock from './items/clock.ts'; import Clock from './items/clock.ts';
import NotifButton from './items/notif-button.ts'; import NotifButton from './items/notif-button.ts';
import RazerStats from './items/razer-stats.ts'; import RazerStats from './items/razer-stats.ts';
@ -9,19 +11,17 @@ import SysTray from './items/systray.ts';
const PADDING = 20; const PADDING = 20;
export default () => BarRevealer({
export default () => Window({ monitor: 1,
name: 'bar',
layer: 'overlay',
exclusivity: 'exclusive', exclusivity: 'exclusive',
anchor: ['bottom', 'left', 'right'], anchor: ['bottom', 'left', 'right'],
monitor: 1, bar: Box({
child: Box({
vertical: true, vertical: true,
children: [ children: [
CenterBox({ CenterBox({
class_name: 'bar', class_name: 'bar',
hexpand: true,
start_widget: Box({ start_widget: Box({
hpack: 'start', hpack: 'start',
children: [ children: [

View file

@ -1,86 +1,117 @@
const Hyprland = await Service.import('hyprland'); const Hyprland = await Service.import('hyprland');
const { Box, EventBox, Revealer, Window } = Widget; const { Box, EventBox, Revealer, Window } = Widget;
// Types
import { Variable as Var } from 'types/variable';
import { BoxGeneric, DefaultProps } from 'global-types';
const FullscreenState = Variable({
const BarCloser = (variable: Var<boolean>) => Window({ fullscreen: false,
name: 'bar-closer', monitors: [] as number[],
visible: false, clientAddrs: new Map() as Map<number, string>,
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',
}),
}),
}); });
export default (props?: DefaultProps) => { Hyprland.connect('event', (hyprObj) => {
const Revealed = Variable(true); const arrayEquals = (a1: unknown[], a2: unknown[]) =>
const barCloser = BarCloser(Revealed); a1.sort().toString() === a2.sort().toString();
const mapEquals = (m1: Map<number, string>, m2: Map<number, string>) =>
m1.size === m2.size &&
Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key));
return Box({ const fs = FullscreenState.value;
css: 'min-height: 1px', const fsClients = hyprObj.clients.filter((c) => c.fullscreen);
hexpand: true,
vertical: true,
setup: (self) => { const fullscreen = fsClients.length > 0;
const checkCurrentWsFsState = () => { const monitors = fsClients.map((c) => c.monitor);
const workspace = Hyprland.getWorkspace( const clientAddrs = new Map(fsClients.map((c) => [c.monitor, c.address]));
Hyprland.active.workspace.id,
);
if (workspace) { const hasChanged = fullscreen !== fs.fullscreen ||
Revealed.setValue(!workspace['hasfullscreen']); !arrayEquals(monitors, fs.monitors) ||
} !mapEquals(clientAddrs, fs.clientAddrs);
};
const checkGlobalFsState = (_: BoxGeneric, fullscreen: boolean) => { if (hasChanged) {
Revealed.setValue(!fullscreen); FullscreenState.setValue({
}; fullscreen,
monitors,
clientAddrs,
});
}
});
self export default ({ bar, monitor = 0, ...rest }) => {
.hook(Hyprland.active, checkCurrentWsFsState) const BarVisible = Variable(true);
.hook(Hyprland, checkGlobalFsState, 'fullscreen');
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: [ child: EventBox({
Revealer({ child: Box({
...props, css: 'min-height: 1px; padding: 1px;',
transition: 'slide_down', hexpand: true,
reveal_child: true, hpack: 'fill',
vertical: true,
}).bind('reveal_child', Revealed), children: [
Box({
Revealer({ css: 'min-height: 10px',
reveal_child: Revealed.bind() visible: BarVisible.bind().as((v) => !v),
.transform((v) => !v),
child: EventBox({
on_hover: () => {
barCloser.visible = true;
Revealed.setValue(true);
},
child: Box({
css: 'min-height: 5px;',
}), }),
}),
Revealer({
transition: 'slide_up',
reveal_child: BarVisible.bind(),
child: bar,
}),
],
}), }),
], }).on('enter-notify-event', () => {
if (!BarVisible.value) {
barCloser.visible = true;
BarVisible.setValue(true);
}
}),
}); });
}; };

View file

@ -1,4 +1,4 @@
const { Window, CenterBox, Box } = Widget; const { CenterBox, Box } = Widget;
import Separator from '../misc/separator.ts'; import Separator from '../misc/separator.ts';
@ -13,73 +13,68 @@ import SysTray from './items/systray.ts';
import TabletToggle from './items/tablet-toggle.ts'; import TabletToggle from './items/tablet-toggle.ts';
import Workspaces from './items/workspaces.ts'; import Workspaces from './items/workspaces.ts';
import BarReveal from './fullscreen.ts'; import BarRevealer from './fullscreen.ts';
const SPACING = 12; const SPACING = 12;
export default () => Window({ export default () => BarRevealer({
name: 'bar',
layer: 'overlay',
anchor: ['top', 'left', 'right'], anchor: ['top', 'left', 'right'],
margins: [-1, 0, 0, 0],
exclusivity: 'exclusive', exclusivity: 'exclusive',
child: BarReveal({ bar: CenterBox({
child: CenterBox({ css: 'margin: 5px 5px 5px 5px',
css: 'margin: 6px 5px 5px 5px', class_name: 'bar',
class_name: 'bar',
start_widget: Box({ start_widget: Box({
hpack: 'start', hpack: 'start',
children: [ 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({ center_widget: Box({
children: [ children: [
Separator(SPACING), Separator(SPACING),
Clock(), Clock(),
Separator(SPACING), Separator(SPACING),
], ],
}), }),
end_widget: Box({ end_widget: Box({
hpack: 'end', hpack: 'end',
children: [ children: [
Heart(), Heart(),
Separator(SPACING), Separator(SPACING),
Battery(), Battery(),
Separator(SPACING), Separator(SPACING),
NotifButton(), NotifButton(),
Separator(SPACING), Separator(SPACING),
QsToggle(), QsToggle(),
], ],
}),
}), }),
}), }),
}); });