chore: make workspaces fit in a single widget, add keyboard support for the logout menu

This commit is contained in:
retrozinndev
2025-06-28 13:29:33 -03:00
parent dece2776fe
commit 2bca31e601
9 changed files with 276 additions and 239 deletions
-12
View File
@@ -7,10 +7,6 @@ import { Media } from "../widget/bar/Media";
import { Apps } from "../widget/bar/Apps";
import { Clock } from "../widget/bar/Clock";
import { Status } from "../widget/bar/Status";
import { SpecialWorkspaces } from "../widget/bar/SpecialWorkspaces";
import { Separator, SeparatorProps } from "../widget/Separator";
import AstalHyprland from "gi://AstalHyprland?version=0.1";
import { bind } from "astal";
export const Bar = (mon: number) => {
const widgetSpacing = 4;
@@ -36,14 +32,6 @@ export const Bar = (mon: number) => {
spacing: widgetSpacing,
children: [
Apps(),
SpecialWorkspaces(),
Separator({
alpha: .2,
orientation: Gtk.Orientation.HORIZONTAL,
margin: 14,
visible: bind(AstalHyprland.get_default(), "workspaces").as(wss =>
wss.filter(ws => ws.id < 0).length > 0)
} as SeparatorProps),
Workspaces(),
FocusedClient()
]
+69 -57
View File
@@ -1,7 +1,7 @@
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
import { getDateTime } from "../scripts/time";
import { execAsync, Gio, GLib } from "astal";
import { AskPopup } from "../widget/AskPopup";
import { AskPopup, AskPopupProps } from "../widget/AskPopup";
import { Windows } from "../windows";
import { Notifications } from "../scripts/notifications";
import AstalNotifd from "gi://AstalNotifd";
@@ -60,80 +60,32 @@ export const LogoutMenu = (mon: number) => new Widget.Window({
image: new Widget.Icon({
icon: "system-shutdown-symbolic"
} as Widget.IconProps),
onClick: () => AskPopup({
title: "Power Off",
text: "Are you sure you want to power off? Unsaved work will be lost.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync("systemctl poweroff");
}
})
onClick: () => AskPopup(poweroffAsk),
onActivate: () => AskPopup(poweroffAsk)
} as Widget.ButtonProps),
new Widget.Button({
className: "reboot",
image: new Widget.Icon({
icon: "arrow-circular-top-right-symbolic"
} as Widget.IconProps),
onClick: () => AskPopup({
title: "Reboot",
text: "Are you sure you want to Reboot? Unsaved work will be lost.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync("systemctl reboot");
}
})
onClick: () => AskPopup(rebootAsk),
onActivate: () => AskPopup(rebootAsk)
} as Widget.ButtonProps),
new Widget.Button({
className: "suspend",
image: new Widget.Icon({
icon: "weather-clear-night-symbolic"
} as Widget.IconProps),
onClick: () => AskPopup({
title: "Suspend",
text: "Are you sure you want to Suspend?",
onAccept: () => execAsync("systemctl suspend")
})
onClick: () => AskPopup(suspendAsk),
onActivate: () => AskPopup(suspendAsk)
} as Widget.ButtonProps),
new Widget.Button({
className: "logout",
image: new Widget.Icon({
icon: "system-log-out-symbolic"
} as Widget.IconProps),
onClick: () => AskPopup({
title: "Log out",
text: "Are you sure you want to log out? Your session will be ended.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync(`hyprctl dispatch exit`).catch((err: Gio.IOErrorEnum) =>
Notifications.getDefault().sendNotification({
appName: "colorshell",
summary: "Couldn't exit Hyprland",
body: `An error occurred and colorshell couldn't exit Hyprland. Stderr: \n${
err.message ? `${err.message}\n` : ""}${err.stack}`,
urgency: AstalNotifd.Urgency.NORMAL,
actions: [{
text: "Report Issue on colorshell",
onAction: () => execAsync(
`xdg-open https://github.com/retrozinndev/colorshell/issues/new`
).catch((err: Gio.IOErrorEnum) =>
Notifications.getDefault().sendNotification({
appName: "colorshell",
summary: "Couldn't open link",
body: `Do you have \`xdg-utils\` installed? Stderr: \n${
err.message ? `${err.message}\n` : ""}${err.stack}`
})
)
}]
})
)
}
})
onClick: () => AskPopup(logoutAsk),
onActivate: () => AskPopup(logoutAsk)
} as Widget.ButtonProps),
]
} as Widget.BoxProps)
@@ -141,3 +93,63 @@ export const LogoutMenu = (mon: number) => new Widget.Window({
})
} as Widget.EventBoxProps)
} as Widget.WindowProps);
const logoutAsk: AskPopupProps = {
title: "Log out",
text: "Are you sure you want to log out? Your session will be ended.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync(`hyprctl dispatch exit`).catch((err: Gio.IOErrorEnum) =>
Notifications.getDefault().sendNotification({
appName: "colorshell",
summary: "Couldn't exit Hyprland",
body: `An error occurred and colorshell couldn't exit Hyprland. Stderr: \n${
err.message ? `${err.message}\n` : ""}${err.stack}`,
urgency: AstalNotifd.Urgency.NORMAL,
actions: [{
text: "Report Issue on colorshell",
onAction: () => execAsync(
`xdg-open https://github.com/retrozinndev/colorshell/issues/new`
).catch((err: Gio.IOErrorEnum) =>
Notifications.getDefault().sendNotification({
appName: "colorshell",
summary: "Couldn't open link",
body: `Do you have \`xdg-utils\` installed? Stderr: \n${
err.message ? `${err.message}\n` : ""}${err.stack}`
})
)
}]
})
)
}
};
const suspendAsk: AskPopupProps = {
title: "Suspend",
text: "Are you sure you want to Suspend?",
onAccept: () => execAsync("systemctl suspend")
};
const rebootAsk: AskPopupProps = {
title: "Reboot",
text: "Are you sure you want to Reboot? Unsaved work will be lost.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync("systemctl reboot");
}
};
const poweroffAsk: AskPopupProps = {
title: "Power Off",
text: "Are you sure you want to power off? Unsaved work will be lost.",
onAccept: () => {
Config.getDefault().getProperty("night_light.save_on_shutdown", "boolean") &&
NightLight.getDefault().saveData();
execAsync("systemctl poweroff");
}
};