import { Astal, Gdk, Gtk } from "ags/gtk4"; import { execAsync } from "ags/process"; import { AskPopup, AskPopupProps } from "../widget/AskPopup"; import { Windows } from "../windows"; import { Notifications } from "../scripts/notifications"; import { NightLight } from "../scripts/nightlight"; import { Config } from "../scripts/config"; import AstalNotifd from "gi://AstalNotifd"; import Gio from "gi://Gio?version=2.0"; import GObject from "gi://GObject?version=2.0"; import { time } from "../scripts/utils"; import { onCleanup } from "ags"; const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor; export const LogoutMenu = (mon: number) => { const conns: Map = new Map(); const controllerKey = Gtk.EventControllerKey.new(); self.add_controller(controllerKey); conns.set(controllerKey, controllerKey.connect("key-released", (_, keyval) => { if(keyval === Gdk.KEY_Escape) self.destroy(); })); onCleanup(() => conns.forEach((id, obj) => obj.disconnect(id))); }}> { const conns: Map = new Map(); const gestureClick = Gtk.GestureClick.new(); self.add_controller(gestureClick); conns.set(gestureClick, gestureClick.connect("released", (gesture) => { if(gesture.get_current_button() === Gdk.BUTTON_PRIMARY) { Windows.getDefault().close("logout-menu"); return true; } })); onCleanup(() => conns.forEach((id, obj) => obj.disconnect(id))); }}> t.format("%H:%M")!)} /> d.format("%A, %B %d %Y")!)} /> AskPopup(poweroffAsk)} onActivate={() => AskPopup(poweroffAsk)} /> AskPopup(rebootAsk)} onActivate={() => AskPopup(rebootAsk)} /> AskPopup(suspendAsk)} onActivate={() => AskPopup(suspendAsk)} /> AskPopup(logoutAsk)} onActivate={() => AskPopup(logoutAsk)} /> as Astal.Window; 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"); } };