🔧 chore(widget/bar/workspaces): add new feature to hide if there's only a single workspace available

This commit is contained in:
retrozinndev
2025-08-25 21:30:51 -03:00
parent 9057a23477
commit bc2b851573
2 changed files with 56 additions and 90 deletions
+13 -36
View File
@@ -20,23 +20,10 @@ export const Media = () => {
: obj.disconnect(id) : obj.disconnect(id)
)); ));
return <Gtk.Box class={"media"} visible={player((pl) => pl.available)} return <Gtk.Box class={"media"} visible={player((pl) => pl.available)}>
$={(self) => { <Gtk.EventControllerScroll $={(self) => {
const gestureClick = Gtk.GestureClick.new(), self.set_flags(Gtk.EventControllerScrollFlags.VERTICAL)
controllerMotion = Gtk.EventControllerMotion.new(), }} onScroll={(_, __, dy) => {
controllerScroll = Gtk.EventControllerScroll.new(
Gtk.EventControllerScrollFlags.VERTICAL
);
self.add_controller(gestureClick);
self.add_controller(controllerMotion);
self.add_controller(controllerScroll);
connections.set(gestureClick, gestureClick.connect("released", () =>
Windows.getDefault().toggle("center-window")));
connections.set(controllerScroll,
controllerScroll.connect("scroll", (_, _dx, dy) => {
if(AstalMpris.get_default().players.length === 1 && if(AstalMpris.get_default().players.length === 1 &&
player.get()?.busName === AstalMpris.get_default().players[0].busName) player.get()?.busName === AstalMpris.get_default().players[0].busName)
return true; return true;
@@ -61,27 +48,17 @@ export const Media = () => {
} }
return true; return true;
}) }}
); />
<Gtk.GestureClick onReleased={() => Windows.getDefault().toggle("center-window")} />
connections.set(controllerMotion, [ <Gtk.EventControllerMotion onEnter={(self) => {
controllerMotion.connect("enter", () => { const revealer = self.get_widget()!.get_last_child() as Gtk.Revealer;
const revealer = self.get_last_child() as Gtk.Revealer;
revealer.set_reveal_child(true); revealer.set_reveal_child(true);
}), }} onLeave={(self) => {
controllerMotion.connect("leave", () => { const revealer = self.get_widget()!.get_last_child() as Gtk.Revealer;
const revealer = self.get_last_child() as Gtk.Revealer;
revealer.set_reveal_child(false); revealer.set_reveal_child(false);
}) }}
]); />
connections.set(self, self.connect("destroy", () =>
connections.forEach((ids, obj) => Array.isArray(ids) ?
ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids))
));
}}>
<Gtk.Box spacing={4} visible={player(pl => pl.available)}> <Gtk.Box spacing={4} visible={player(pl => pl.available)}>
<With value={player(pl => pl.available)}> <With value={player(pl => pl.available)}>
{(available: boolean) => available && <Gtk.Box> {(available: boolean) => available && <Gtk.Box>
+23 -34
View File
@@ -1,12 +1,11 @@
import { Gtk } from "ags/gtk4"; import { Gtk } from "ags/gtk4";
import AstalHyprland from "gi://AstalHyprland";
import { getAppIcon, getSymbolicIcon } from "../../modules/apps"; import { getAppIcon, getSymbolicIcon } from "../../modules/apps";
import { Separator } from "../Separator"; import { Separator } from "../Separator";
import { generalConfig } from "../../app"; import { generalConfig } from "../../app";
import { createBinding, createComputed, createState, For, With } from "ags"; import { createBinding, createComputed, createState, For, With } from "ags";
import { variableToBoolean } from "../../modules/utils"; import { variableToBoolean } from "../../modules/utils";
import GObject from "ags/gobject"; import AstalHyprland from "gi://AstalHyprland";
const [showNumbers, setShowNumbers] = createState(false); const [showNumbers, setShowNumbers] = createState(false);
@@ -19,10 +18,15 @@ export const Workspaces = () => {
defaultWorkspaces = workspaces.as(wss => defaultWorkspaces = workspaces.as(wss =>
wss.filter(ws => ws.id > 0).sort((a, b) => a.id - b.id)), wss.filter(ws => ws.id > 0).sort((a, b) => a.id - b.id)),
specialWorkspaces = workspaces.as(wss => specialWorkspaces = workspaces.as(wss =>
wss.filter(ws => ws.id < 0).sort((a, b) => a.id - b.id)); wss.filter(ws => ws.id < 0).sort((a, b) => a.id - b.id)),
focusedWorkspace = createBinding(AstalHyprland.get_default(), "focusedWorkspace");
return <Gtk.Box class={"workspaces-row"}> return <Gtk.Box class={"workspaces-row"} visible={createComputed([
workspaces.as(wss => wss.length <= 1),
generalConfig.bindProperty("workspaces.hide_if_single", "boolean")
], (hideable, enabled) => enabled && hideable ? false : true
)}>
<Gtk.Box class={"special-workspaces"} spacing={4}> <Gtk.Box class={"special-workspaces"} spacing={4}>
<For each={specialWorkspaces}> <For each={specialWorkspaces}>
{(ws: AstalHyprland.Workspace) => {(ws: AstalHyprland.Workspace) =>
@@ -54,34 +58,19 @@ export const Workspaces = () => {
margin={12} spacing={8} visible={variableToBoolean(specialWorkspaces)} margin={12} spacing={8} visible={variableToBoolean(specialWorkspaces)}
/> />
</Gtk.Revealer> </Gtk.Revealer>
<Gtk.Box class={"default-workspaces"} spacing={4} $={(self) => { <Gtk.Box class={"default-workspaces"} spacing={4}>
const conns: Map<GObject.Object, Array<number>|number> = new Map(); <Gtk.EventControllerScroll $={(self) => self.set_flags(Gtk.EventControllerScrollFlags.VERTICAL)}
const controllerScroll = Gtk.EventControllerScroll.new( onScroll={(_, __, dy) => {
Gtk.EventControllerScrollFlags.VERTICAL
), controllerMotion = Gtk.EventControllerMotion.new();
self.add_controller(controllerScroll);
self.add_controller(controllerMotion);
conns.set(controllerScroll, controllerScroll.connect("scroll", (_, _dx, dy) => {
dy > 0 ? dy > 0 ?
AstalHyprland.get_default().dispatch("workspace", "e-1") AstalHyprland.get_default().dispatch("workspace", "e-1")
: AstalHyprland.get_default().dispatch("workspace", "e+1"); : AstalHyprland.get_default().dispatch("workspace", "e+1");
return true; return true;
})); }}
/>
conns.set(controllerMotion, [ <Gtk.EventControllerMotion onEnter={() => setShowNumbers(true)}
controllerMotion.connect("enter", () => setShowNumbers(true)), onLeave={() => setShowNumbers(false)}
controllerMotion.connect("leave", () => setShowNumbers(false)) />
]);
conns.set(self, self.connect("destroy", () => conns.forEach((ids, obj) =>
Array.isArray(ids) ?
ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids)
)));
}}>
<For each={defaultWorkspaces}> <For each={defaultWorkspaces}>
{(ws: AstalHyprland.Workspace, i) => { {(ws: AstalHyprland.Workspace, i) => {
const showId = createComputed([ const showId = createComputed([
@@ -122,20 +111,20 @@ export const Workspaces = () => {
`${lastClient.get_class()}: ` `${lastClient.get_class()}: `
: "" : ""
} ${lastClient.title}` : "" }` } ${lastClient.title}` : "" }`
)} onClicked={() => ws.focus()}> )} onClicked={() => focusedWorkspace.get()?.id !== ws.id && ws.focus()}>
<With value={createBinding(ws, "lastClient")}> <With value={createBinding(ws, "lastClient")}>
{(lastClient: AstalHyprland.Client) => {(lastClient: AstalHyprland.Client) =>
<Gtk.Box class={"last-client"} hexpand> <Gtk.Box class={"last-client"} hexpand>
<Gtk.Revealer transitionDuration={280} revealChild={showId} <Gtk.Revealer transitionDuration={280} revealChild={showId}
transitionType={createBinding(AstalHyprland.get_default(), "focusedWorkspace") transitionType={focusedWorkspace.as(
.as(fws => fws.id !== ws.id ? fws => fws.id !== ws.id ?
Gtk.RevealerTransitionType.SLIDE_LEFT Gtk.RevealerTransitionType.SLIDE_LEFT
: Gtk.RevealerTransitionType.SLIDE_RIGHT)}> : Gtk.RevealerTransitionType.SLIDE_RIGHT
)}>
<Gtk.Label label={createBinding(ws, "id").as(String)} <Gtk.Label label={createBinding(ws, "id").as(String)}
class={"id"} hexpand /> class={"id"} hexpand
/>
</Gtk.Revealer> </Gtk.Revealer>
{lastClient && <Gtk.Image class={"last-client-icon"} iconName={ {lastClient && <Gtk.Image class={"last-client-icon"} iconName={
createBinding(lastClient, "initialClass").as(initialClass => createBinding(lastClient, "initialClass").as(initialClass =>