refactor(ags): remake fullscreen bar hiding from scratch
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
66a6a7a417
commit
0ce1b48631
4 changed files with 151 additions and 119 deletions
|
@ -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>;
|
||||||
|
|
|
@ -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: [
|
||||||
|
|
|
@ -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({
|
||||||
|
fullscreen: false,
|
||||||
|
monitors: [] as number[],
|
||||||
|
clientAddrs: new Map() as Map<number, string>,
|
||||||
|
});
|
||||||
|
|
||||||
const BarCloser = (variable: Var<boolean>) => Window({
|
Hyprland.connect('event', (hyprObj) => {
|
||||||
name: 'bar-closer',
|
const arrayEquals = (a1: unknown[], a2: unknown[]) =>
|
||||||
|
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));
|
||||||
|
|
||||||
|
const fs = FullscreenState.value;
|
||||||
|
const fsClients = hyprObj.clients.filter((c) => c.fullscreen);
|
||||||
|
|
||||||
|
const fullscreen = fsClients.length > 0;
|
||||||
|
const monitors = fsClients.map((c) => c.monitor);
|
||||||
|
const clientAddrs = new Map(fsClients.map((c) => [c.monitor, c.address]));
|
||||||
|
|
||||||
|
const hasChanged = fullscreen !== fs.fullscreen ||
|
||||||
|
!arrayEquals(monitors, fs.monitors) ||
|
||||||
|
!mapEquals(clientAddrs, fs.clientAddrs);
|
||||||
|
|
||||||
|
if (hasChanged) {
|
||||||
|
FullscreenState.setValue({
|
||||||
|
fullscreen,
|
||||||
|
monitors,
|
||||||
|
clientAddrs,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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,
|
visible: false,
|
||||||
|
monitor,
|
||||||
anchor: ['top', 'bottom', 'left', 'right'],
|
anchor: ['top', 'bottom', 'left', 'right'],
|
||||||
layer: 'overlay',
|
layer: 'overlay',
|
||||||
|
|
||||||
child: EventBox({
|
child: EventBox({
|
||||||
on_hover: (self) => {
|
on_hover: (self) => {
|
||||||
variable.setValue(false);
|
|
||||||
const parent = self.get_parent();
|
const parent = self.get_parent();
|
||||||
|
|
||||||
if (parent) {
|
parent?.set_visible(false);
|
||||||
parent.visible = false;
|
BarVisible.setValue(false);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
css: 'padding: 1px',
|
css: 'padding: 1px;',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default (props?: DefaultProps) => {
|
return Window({
|
||||||
const Revealed = Variable(true);
|
name: `bar-${monitor}`,
|
||||||
const barCloser = BarCloser(Revealed);
|
layer: 'overlay',
|
||||||
|
monitor,
|
||||||
|
margins: [-1, -1, -1, -1],
|
||||||
|
...rest,
|
||||||
|
|
||||||
return Box({
|
attribute: {
|
||||||
css: 'min-height: 1px',
|
barCloser,
|
||||||
hexpand: true,
|
|
||||||
vertical: true,
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
const checkCurrentWsFsState = () => {
|
|
||||||
const workspace = Hyprland.getWorkspace(
|
|
||||||
Hyprland.active.workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (workspace) {
|
|
||||||
Revealed.setValue(!workspace['hasfullscreen']);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkGlobalFsState = (_: BoxGeneric, fullscreen: boolean) => {
|
|
||||||
Revealed.setValue(!fullscreen);
|
|
||||||
};
|
|
||||||
|
|
||||||
self
|
|
||||||
.hook(Hyprland.active, checkCurrentWsFsState)
|
|
||||||
.hook(Hyprland, checkGlobalFsState, 'fullscreen');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
children: [
|
|
||||||
Revealer({
|
|
||||||
...props,
|
|
||||||
transition: 'slide_down',
|
|
||||||
reveal_child: true,
|
|
||||||
|
|
||||||
}).bind('reveal_child', Revealed),
|
|
||||||
|
|
||||||
Revealer({
|
|
||||||
reveal_child: Revealed.bind()
|
|
||||||
.transform((v) => !v),
|
|
||||||
|
|
||||||
child: EventBox({
|
child: EventBox({
|
||||||
on_hover: () => {
|
|
||||||
barCloser.visible = true;
|
|
||||||
Revealed.setValue(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
css: 'min-height: 5px;',
|
css: 'min-height: 1px; padding: 1px;',
|
||||||
}),
|
hexpand: true,
|
||||||
|
hpack: 'fill',
|
||||||
|
vertical: true,
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,20 +13,16 @@ 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({
|
||||||
|
@ -81,5 +77,4 @@ export default () => Window({
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue