feat(agsV2): implement fullscreen bar toggle
All checks were successful
Discord / discord commits (push) Has been skipped

This commit is contained in:
matt1432 2024-09-26 15:55:32 -04:00
parent 1ee6bf65f2
commit 56e2caf76e
3 changed files with 136 additions and 25 deletions

View file

@ -9,7 +9,7 @@ export const get_hyprland_monitor = (monitor: Gdk.Monitor): AstalHyprland.Monito
const model = monitor.model?.replace(',', ''); const model = monitor.model?.replace(',', '');
const start = `${manufacturer} ${model}`; const start = `${manufacturer} ${model}`;
return Hyprland.monitors.find((m) => m.description?.startsWith(start)); return Hyprland.get_monitors().find((m) => m.description?.startsWith(start));
}; };
export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => { export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => {
@ -17,7 +17,7 @@ export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => {
const model = monitor.model?.replace(',', ''); const model = monitor.model?.replace(',', '');
const start = `${manufacturer} ${model}`; const start = `${manufacturer} ${model}`;
return `desc:${Hyprland.monitors.find((m) => m.description?.startsWith(start))?.description}`; return `desc:${Hyprland.get_monitors().find((m) => m.description?.startsWith(start))?.description}`;
}; };
export const get_gdkmonitor_from_desc = (desc: string): Gdk.Monitor => { export const get_gdkmonitor_from_desc = (desc: string): Gdk.Monitor => {

View file

@ -1,9 +1,9 @@
import { Variable } from 'astal'; import { Astal, bind, Gdk, Gtk, Variable, Widget } from 'astal';
import AstalHyprland from 'gi://AstalHyprland?version=0.1'; import AstalHyprland from 'gi://AstalHyprland?version=0.1';
const Hyprland = AstalHyprland.get_default(); const Hyprland = AstalHyprland.get_default();
import { get_monitor_desc } from '../../lib'; import { get_hyprland_monitor_desc, get_monitor_desc } from '../../lib';
const FullscreenState = Variable({ const FullscreenState = Variable({
@ -23,8 +23,7 @@ Hyprland.connect('event', () => {
const fsClients = Hyprland.get_clients().filter((c) => { const fsClients = Hyprland.get_clients().filter((c) => {
const mon = c.get_monitor(); const mon = c.get_monitor();
return c.fullscreen && return c.fullscreen && c.workspace.id === mon?.activeWorkspace.id;
c.workspace.id === mon?.activeWorkspace.id;
}); });
const monitors = fsClients.map((c) => const monitors = fsClients.map((c) =>
@ -47,4 +46,127 @@ Hyprland.connect('event', () => {
} }
}); });
export default FullscreenState; export default ({
anchor,
gdkmonitor = Gdk.Display.get_default()?.get_monitor(0) as Gdk.Monitor,
child,
...rest
}: Widget.WindowProps) => {
const monitor = get_hyprland_monitor_desc(gdkmonitor);
const BarVisible = Variable(true);
FullscreenState.subscribe((v) => {
BarVisible.set(!v.monitors.includes(monitor));
});
const barCloser = (
<window
name={`bar-${monitor}-closer`}
css="all: unset;"
visible={false}
gdkmonitor={gdkmonitor}
layer={Astal.Layer.OVERLAY}
anchor={
Astal.WindowAnchor.TOP |
Astal.WindowAnchor.BOTTOM |
Astal.WindowAnchor.LEFT |
Astal.WindowAnchor.RIGHT
}
>
<eventbox
on_hover={() => {
barCloser.visible = false;
BarVisible.set(false);
}}
>
<box css="padding: 1px;" />
</eventbox>
</window>
);
// Hide bar instantly when out of focus
Hyprland.connect('notify::focused-workspace', () => {
const addr = FullscreenState.get().clientAddrs.get(monitor);
if (addr) {
const client = Hyprland.get_client(addr);
if (client?.workspace.id !== Hyprland.get_focused_workspace().get_id()) {
BarVisible.set(true);
barCloser.visible = false;
}
else {
BarVisible.set(false);
barCloser.visible = true;
}
}
});
const buffer = (
<box
css="min-height: 10px;"
visible={bind(BarVisible).as((v) => !v)}
/>
);
const vertical = anchor >= (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT);
const isBottomOrLeft = (
anchor === (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM)
) || (
anchor === (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM)
);
let transition: Gtk.RevealerTransitionType;
if (vertical) {
transition = isBottomOrLeft ?
Gtk.RevealerTransitionType.SLIDE_UP :
Gtk.RevealerTransitionType.SLIDE_DOWN;
}
else {
transition = isBottomOrLeft ?
Gtk.RevealerTransitionType.SLIDE_RIGHT :
Gtk.RevealerTransitionType.SLIDE_LEFT;
}
const barWrap = (
<revealer
reveal_child={bind(BarVisible)}
transitionType={transition}
>
{child}
</revealer>
);
return (
<window
name={`bar-${monitor}`}
layer={Astal.Layer.OVERLAY}
gdkmonitor={gdkmonitor}
margins={[-1, -1, -1, -1]}
anchor={anchor}
{...rest}
>
<eventbox
onHover={() => {
if (!BarVisible.get()) {
barCloser.visible = true;
BarVisible.set(true);
}
}}
>
<box
css="min-height: 1px; padding: 1px;"
hexpand={true}
hpack="fill"
vertical={vertical}
>
{isBottomOrLeft ?
[buffer, barWrap] :
[barWrap, buffer]}
</box>
</eventbox>
</window>
);
};

View file

@ -1,34 +1,23 @@
import { Astal, bind, Gtk, idle, Variable } from 'astal'; import { Astal } from 'astal';
import FullscreenState from './fullscreen'; import BarRevealer from './fullscreen';
FullscreenState.subscribe((v) => {
console.log(v);
});
const isVisible = Variable<boolean>(false);
export default () => { export default () => {
return ( return (
<window <BarRevealer
className="Bar"
exclusivity={Astal.Exclusivity.EXCLUSIVE} exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={ anchor={
Astal.WindowAnchor.TOP | Astal.WindowAnchor.TOP |
Astal.WindowAnchor.LEFT | Astal.WindowAnchor.LEFT |
Astal.WindowAnchor.RIGHT Astal.WindowAnchor.RIGHT
} }
setup={() => idle(() => {
isVisible.set(true);
})}
> >
<revealer <box
revealChild={bind(isVisible)} className="Bar"
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
transitionDuration={500}
> >
<label label="hi" /> <label label="hi" />
</revealer> </box>
</window> </BarRevealer>
); );
}; };