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 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 => {
@ -17,7 +17,7 @@ export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => {
const model = monitor.model?.replace(',', '');
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 => {

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';
const Hyprland = AstalHyprland.get_default();
import { get_monitor_desc } from '../../lib';
import { get_hyprland_monitor_desc, get_monitor_desc } from '../../lib';
const FullscreenState = Variable({
@ -23,8 +23,7 @@ Hyprland.connect('event', () => {
const fsClients = Hyprland.get_clients().filter((c) => {
const mon = c.get_monitor();
return c.fullscreen &&
c.workspace.id === mon?.activeWorkspace.id;
return c.fullscreen && c.workspace.id === mon?.activeWorkspace.id;
});
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 () => {
return (
<window
className="Bar"
<BarRevealer
exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={
Astal.WindowAnchor.TOP |
Astal.WindowAnchor.LEFT |
Astal.WindowAnchor.RIGHT
}
setup={() => idle(() => {
isVisible.set(true);
})}
>
<revealer
revealChild={bind(isVisible)}
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
transitionDuration={500}
<box
className="Bar"
>
<label label="hi" />
</revealer>
</window>
</box>
</BarRevealer>
);
};