Remove old preparation
This commit is contained in:
		
							
								
								
									
										2
									
								
								config/general/ags/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								config/general/ags/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| node_modules/ | ||||
| @girs/ | ||||
| @@ -1,12 +0,0 @@ | ||||
| import { App } from "astal/gtk3" | ||||
| import style from "./style.scss" | ||||
| import Bar from "./bar/Bar" | ||||
| import OSD from "./osd/OSD" | ||||
|  | ||||
| App.start({ | ||||
|     css: style, | ||||
|     main() { | ||||
|         App.get_monitors().map(Bar); | ||||
|         OSD(App.get_monitors()[0]); | ||||
|     }, | ||||
| }) | ||||
							
								
								
									
										21
									
								
								config/general/ags/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								config/general/ags/env.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -1,21 +0,0 @@ | ||||
| declare const SRC: string | ||||
|  | ||||
| declare module "inline:*" { | ||||
|     const content: string | ||||
|     export default content | ||||
| } | ||||
|  | ||||
| declare module "*.scss" { | ||||
|     const content: string | ||||
|     export default content | ||||
| } | ||||
|  | ||||
| declare module "*.blp" { | ||||
|     const content: string | ||||
|     export default content | ||||
| } | ||||
|  | ||||
| declare module "*.css" { | ||||
|     const content: string | ||||
|     export default content | ||||
| } | ||||
| @@ -1,125 +0,0 @@ | ||||
| @use "sass:string"; | ||||
|  | ||||
| @function gtkalpha($c, $a) { | ||||
|     @return string.unquote("alpha(#{$c},#{$a})"); | ||||
| } | ||||
|  | ||||
| // https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss | ||||
| $fg-color: #{"@theme_fg_color"}; | ||||
| $bg-color: #{"@theme_bg_color"}; | ||||
| $error: red; | ||||
|  | ||||
| window.NotificationPopups { | ||||
|     all: unset; | ||||
| } | ||||
|  | ||||
| eventbox.Notification { | ||||
|  | ||||
|     &:first-child>box { | ||||
|         margin-top: 1rem; | ||||
|     } | ||||
|  | ||||
|     &:last-child>box { | ||||
|         margin-bottom: 1rem; | ||||
|     } | ||||
|  | ||||
|     // eventboxes can not take margins so we style its inner box instead | ||||
|     >box { | ||||
|         min-width: 400px; | ||||
|         border-radius: 13px; | ||||
|         background-color: $bg-color; | ||||
|         margin: .5rem 1rem .5rem 1rem; | ||||
|         box-shadow: 2px 3px 8px 0 gtkalpha(black, .4); | ||||
|         border: 1pt solid gtkalpha($fg-color, .03); | ||||
|     } | ||||
|  | ||||
|     &.critical>box { | ||||
|         border: 1pt solid gtkalpha($error, .4); | ||||
|  | ||||
|         .header { | ||||
|  | ||||
|             .app-name { | ||||
|                 color: gtkalpha($error, .8); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             .app-icon { | ||||
|                 color: gtkalpha($error, .6); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .header { | ||||
|         padding: .5rem; | ||||
|         color: gtkalpha($fg-color, 0.5); | ||||
|  | ||||
|         .app-icon { | ||||
|             margin: 0 .4rem; | ||||
|         } | ||||
|  | ||||
|         .app-name { | ||||
|             margin-right: .3rem; | ||||
|             font-weight: bold; | ||||
|  | ||||
|             &:first-child { | ||||
|                 margin-left: .4rem; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         .time { | ||||
|             margin: 0 .4rem; | ||||
|         } | ||||
|  | ||||
|         button { | ||||
|             padding: .2rem; | ||||
|             min-width: 0; | ||||
|             min-height: 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     separator { | ||||
|         margin: 0 .4rem; | ||||
|         background-color: gtkalpha($fg-color, .1); | ||||
|     } | ||||
|  | ||||
|     .content { | ||||
|         margin: 1rem; | ||||
|         margin-top: .5rem; | ||||
|  | ||||
|         .summary { | ||||
|             font-size: 1.2em; | ||||
|             color: $fg-color; | ||||
|         } | ||||
|  | ||||
|         .body { | ||||
|             color: gtkalpha($fg-color, 0.8); | ||||
|         } | ||||
|  | ||||
|         .image { | ||||
|             border: 1px solid gtkalpha($fg-color, .02); | ||||
|             margin-right: .5rem; | ||||
|             border-radius: 9px; | ||||
|             min-width: 100px; | ||||
|             min-height: 100px; | ||||
|             background-size: cover; | ||||
|             background-position: center; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .actions { | ||||
|         margin: 1rem; | ||||
|         margin-top: 0; | ||||
|  | ||||
|         button { | ||||
|             margin: 0 .3rem; | ||||
|  | ||||
|             &:first-child { | ||||
|                 margin-left: 0; | ||||
|             } | ||||
|  | ||||
|             &:last-child { | ||||
|                 margin-right: 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,107 +0,0 @@ | ||||
| import { GLib } from "astal" | ||||
| import { Gtk, Astal } from "astal/gtk3" | ||||
| import { type EventBox } from "astal/gtk3/widget" | ||||
| import Notifd from "gi://AstalNotifd" | ||||
|  | ||||
| const isIcon = (icon: string) => | ||||
|     !!Astal.Icon.lookup_icon(icon) | ||||
|  | ||||
| const fileExists = (path: string) => | ||||
|     GLib.file_test(path, GLib.FileTest.EXISTS) | ||||
|  | ||||
| const time = (time: number, format = "%H:%M") => GLib.DateTime | ||||
|     .new_from_unix_local(time) | ||||
|     .format(format)! | ||||
|  | ||||
| const urgency = (n: Notifd.Notification) => { | ||||
|     const { LOW, NORMAL, CRITICAL } = Notifd.Urgency | ||||
|     // match operator when? | ||||
|     switch (n.urgency) { | ||||
|         case LOW: return "low" | ||||
|         case CRITICAL: return "critical" | ||||
|         case NORMAL: | ||||
|         default: return "normal" | ||||
|     } | ||||
| } | ||||
|  | ||||
| type Props = { | ||||
|     setup(self: EventBox): void | ||||
|     onHoverLost(self: EventBox): void | ||||
|     notification: Notifd.Notification | ||||
| } | ||||
|  | ||||
| export default function Notification(props: Props) { | ||||
|     const { notification: n, onHoverLost, setup } = props | ||||
|     const { START, CENTER, END } = Gtk.Align | ||||
|  | ||||
|     return <eventbox | ||||
|         className={`Notification ${urgency(n)}`} | ||||
|         setup={setup} | ||||
|         onHoverLost={onHoverLost}> | ||||
|         <box vertical> | ||||
|             <box className="header"> | ||||
|                 {(n.appIcon || n.desktopEntry) && <icon | ||||
|                     className="app-icon" | ||||
|                     visible={Boolean(n.appIcon || n.desktopEntry)} | ||||
|                     icon={n.appIcon || n.desktopEntry} | ||||
|                 />} | ||||
|                 <label | ||||
|                     className="app-name" | ||||
|                     halign={START} | ||||
|                     truncate | ||||
|                     label={n.appName || "Unknown"} | ||||
|                 /> | ||||
|                 <label | ||||
|                     className="time" | ||||
|                     hexpand | ||||
|                     halign={END} | ||||
|                     label={time(n.time)} | ||||
|                 /> | ||||
|                 <button onClicked={() => n.dismiss()}> | ||||
|                     <icon icon="window-close-symbolic" /> | ||||
|                 </button> | ||||
|             </box> | ||||
|             <Gtk.Separator visible /> | ||||
|             <box className="content"> | ||||
|                 {n.image && fileExists(n.image) && <box | ||||
|                     valign={START} | ||||
|                     className="image" | ||||
|                     css={`background-image: url('${n.image}')`} | ||||
|                 />} | ||||
|                 {n.image && isIcon(n.image) && <box | ||||
|                     expand={false} | ||||
|                     valign={START} | ||||
|                     className="icon-image"> | ||||
|                     <icon icon={n.image} expand halign={CENTER} valign={CENTER} /> | ||||
|                 </box>} | ||||
|                 <box vertical> | ||||
|                     <label | ||||
|                         className="summary" | ||||
|                         halign={START} | ||||
|                         xalign={0} | ||||
|                         label={n.summary} | ||||
|                         truncate | ||||
|                     /> | ||||
|                     {n.body && <label | ||||
|                         className="body" | ||||
|                         wrap | ||||
|                         useMarkup | ||||
|                         halign={START} | ||||
|                         xalign={0} | ||||
|                         justifyFill | ||||
|                         label={n.body} | ||||
|                     />} | ||||
|                 </box> | ||||
|             </box> | ||||
|             {n.get_actions().length > 0 && <box className="actions"> | ||||
|                 {n.get_actions().map(({ label, id }) => ( | ||||
|                     <button | ||||
|                         hexpand | ||||
|                         onClicked={() => n.invoke(id)}> | ||||
|                         <label label={label} halign={CENTER} hexpand /> | ||||
|                     </button> | ||||
|                 ))} | ||||
|             </box>} | ||||
|         </box> | ||||
|     </eventbox> | ||||
| } | ||||
| @@ -1,105 +0,0 @@ | ||||
| import { Astal, Gtk, Gdk } from "astal/gtk3" | ||||
| import Notifd from "gi://AstalNotifd" | ||||
| import Notification from "./Notification" | ||||
| import { type Subscribable } from "astal/binding" | ||||
| import { Variable, bind, timeout } from "astal" | ||||
|  | ||||
| // see comment below in constructor | ||||
| const TIMEOUT_DELAY = 5000 | ||||
|  | ||||
| // The purpose if this class is to replace Variable<Array<Widget>> | ||||
| // with a Map<number, Widget> type in order to track notification widgets | ||||
| // by their id, while making it conviniently bindable as an array | ||||
| class NotifiationMap implements Subscribable { | ||||
|     // the underlying map to keep track of id widget pairs | ||||
|     private map: Map<number, Gtk.Widget> = new Map() | ||||
|  | ||||
|     // it makes sense to use a Variable under the hood and use its | ||||
|     // reactivity implementation instead of keeping track of subscribers ourselves | ||||
|     private var: Variable<Array<Gtk.Widget>> = Variable([]) | ||||
|  | ||||
|     // notify subscribers to rerender when state changes | ||||
|     private notifiy() { | ||||
|         this.var.set([...this.map.values()].reverse()) | ||||
|     } | ||||
|  | ||||
|     constructor() { | ||||
|         const notifd = Notifd.get_default() | ||||
|  | ||||
|         /** | ||||
|          * uncomment this if you want to | ||||
|          * ignore timeout by senders and enforce our own timeout | ||||
|          * note that if the notification has any actions | ||||
|          * they might not work, since the sender already treats them as resolved | ||||
|          */ | ||||
|         // notifd.ignoreTimeout = true | ||||
|  | ||||
|         notifd.connect("notified", (_, id) => { | ||||
|             this.set(id, Notification({ | ||||
|                 notification: notifd.get_notification(id)!, | ||||
|  | ||||
|                 // once hovering over the notification is done | ||||
|                 // destroy the widget without calling notification.dismiss() | ||||
|                 // so that it acts as a "popup" and we can still display it | ||||
|                 // in a notification center like widget | ||||
|                 // but clicking on the close button will close it | ||||
|                 onHoverLost: () => this.delete(id), | ||||
|  | ||||
|                 // notifd by default does not close notifications | ||||
|                 // until user input or the timeout specified by sender | ||||
|                 // which we set to ignore above | ||||
|                 setup: () => timeout(TIMEOUT_DELAY, () => { | ||||
|                     /** | ||||
|                      * uncomment this if you want to "hide" the notifications | ||||
|                      * after TIMEOUT_DELAY | ||||
|                      */ | ||||
|                     // this.delete(id) | ||||
|                 }) | ||||
|             })) | ||||
|         }) | ||||
|  | ||||
|         // notifications can be closed by the outside before | ||||
|         // any user input, which have to be handled too | ||||
|         notifd.connect("resolved", (_, id) => { | ||||
|             this.delete(id) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     private set(key: number, value: Gtk.Widget) { | ||||
|         // in case of replacecment destroy previous widget | ||||
|         this.map.get(key)?.destroy() | ||||
|         this.map.set(key, value) | ||||
|         this.notifiy() | ||||
|     } | ||||
|  | ||||
|     private delete(key: number) { | ||||
|         this.map.get(key)?.destroy() | ||||
|         this.map.delete(key) | ||||
|         this.notifiy() | ||||
|     } | ||||
|  | ||||
|     // needed by the Subscribable interface | ||||
|     get() { | ||||
|         return this.var.get() | ||||
|     } | ||||
|  | ||||
|     // needed by the Subscribable interface | ||||
|     subscribe(callback: (list: Array<Gtk.Widget>) => void) { | ||||
|         return this.var.subscribe(callback) | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default function NotificationPopups(gdkmonitor: Gdk.Monitor) { | ||||
|     const { TOP, RIGHT } = Astal.WindowAnchor | ||||
|     const notifs = new NotifiationMap() | ||||
|  | ||||
|     return <window | ||||
|         className="NotificationPopups" | ||||
|         gdkmonitor={gdkmonitor} | ||||
|         exclusivity={Astal.Exclusivity.EXCLUSIVE} | ||||
|         anchor={TOP | RIGHT}> | ||||
|         <box vertical noImplicitDestroy> | ||||
|             {bind(notifs)} | ||||
|         </box> | ||||
|     </window> | ||||
| } | ||||
| @@ -1,30 +0,0 @@ | ||||
| $fg-color: #{"@theme_fg_color"}; | ||||
| $bg-color: #{"@theme_bg_color"}; | ||||
|  | ||||
| window.OSD { | ||||
|     box.OSD { | ||||
|         border-radius: 100px; | ||||
|         background-color: $bg-color; | ||||
|         padding: 13px 16px; | ||||
|         margin: 13px; | ||||
|         box-shadow: 3px 3px 7px 0 rgba(0,0,0,.4); | ||||
|     } | ||||
|  | ||||
|     icon { | ||||
|         font-size: 4rem; | ||||
|     } | ||||
|  | ||||
|     label { | ||||
|         font-size: 2.4rem; | ||||
|     } | ||||
|  | ||||
|     levelbar { | ||||
|         trough { | ||||
|             margin: 1 .6rem; | ||||
|         } | ||||
|  | ||||
|         block { | ||||
|             min-height: 2rem; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| // From examples on astal github page, since it looks good by default | ||||
|  | ||||
| import { App, Astal, Gdk, Gtk } from "astal/gtk3" | ||||
| import { timeout } from "astal/time" | ||||
| import Variable from "astal/variable" | ||||
| import Brightness from "./brightness" | ||||
| import Wp from "gi://AstalWp" | ||||
|  | ||||
| function OnScreenProgress({ visible }: { visible: Variable<boolean> }) { | ||||
|     const brightness = Brightness.get_default() | ||||
|     const speaker = Wp.get_default()!.get_default_speaker() | ||||
|  | ||||
|     const iconName = Variable("") | ||||
|     const value = Variable(0) | ||||
|  | ||||
|     let count = 0 | ||||
|     function show(v: number, icon: string) { | ||||
|         visible.set(true) | ||||
|         value.set(v) | ||||
|         iconName.set(icon) | ||||
|         count++ | ||||
|         timeout(2000, () => { | ||||
|             count-- | ||||
|             if (count === 0) visible.set(false) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
|         <revealer | ||||
|             setup={(self) => { | ||||
|                 self.hook(brightness, "notify::screen", () => | ||||
|                     show(brightness.screen, "display-brightness-symbolic"), | ||||
|                 ) | ||||
|  | ||||
|                 if (speaker) { | ||||
|                     self.hook(speaker, "notify::volume", () => | ||||
|                         show(speaker.volume, speaker.volumeIcon), | ||||
|                     ) | ||||
|                 } | ||||
|             }} | ||||
|             revealChild={visible()} | ||||
|             transitionType={Gtk.RevealerTransitionType.SLIDE_UP} | ||||
|         > | ||||
|             <box className="OSD"> | ||||
|                 <icon icon={iconName()} /> | ||||
|                 <levelbar valign={Gtk.Align.CENTER} widthRequest={100} value={value()} /> | ||||
|                 <label label={value(v => `${Math.floor(v * 100)}%`)} /> | ||||
|             </box> | ||||
|         </revealer> | ||||
|     ) | ||||
| } | ||||
|  | ||||
| export default function OSD(monitor: Gdk.Monitor) { | ||||
|     const visible = Variable(false) | ||||
|  | ||||
|     return ( | ||||
|         <window | ||||
|             gdkmonitor={monitor} | ||||
|             className="OSD" | ||||
|             namespace="osd" | ||||
|             application={App} | ||||
|             layer={Astal.Layer.OVERLAY} | ||||
|             keymode={Astal.Keymode.ON_DEMAND} | ||||
|             anchor={Astal.WindowAnchor.BOTTOM} | ||||
|         > | ||||
|             <eventbox onClick={() => visible.set(false)}> | ||||
|                 <OnScreenProgress visible={visible} /> | ||||
|             </eventbox> | ||||
|         </window> | ||||
|     ) | ||||
| } | ||||
| @@ -1,47 +0,0 @@ | ||||
| // From examples on Astal GitHub | ||||
|  | ||||
| import GObject, { register, property } from "astal/gobject" | ||||
| import { monitorFile, readFileAsync } from "astal/file" | ||||
| import { exec, execAsync } from "astal/process" | ||||
|  | ||||
| const get = (args: string) => Number(exec(`brightnessctl ${args}`)) | ||||
| const screen = exec(`bash -c "ls -w1 /sys/class/backlight | head -1"`) | ||||
|  | ||||
| @register({ GTypeName: "Brightness" }) | ||||
| export default class Brightness extends GObject.Object { | ||||
|     static instance: Brightness | ||||
|     static get_default() { | ||||
|         if (!this.instance) | ||||
|             this.instance = new Brightness() | ||||
|  | ||||
|         return this.instance | ||||
|     } | ||||
|  | ||||
|     #screenMax = get("max") | ||||
|     #screen = get("get") / (get("max") || 1) | ||||
|  | ||||
|     @property(Number) | ||||
|     get screen() { return this.#screen } | ||||
|  | ||||
|     set screen(percent) { | ||||
|         if (percent < 0) | ||||
|             percent = 0 | ||||
|  | ||||
|         if (percent > 1) | ||||
|             percent = 1 | ||||
|  | ||||
|         execAsync(`brightnessctl set ${Math.floor(percent * 100)}% -q`).then(() => { | ||||
|             this.#screen = percent | ||||
|             this.notify("screen") | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     constructor() { | ||||
|         super() | ||||
|         monitorFile(`/sys/class/backlight/${screen}/brightness`, async f => { | ||||
|             const v = await readFileAsync(f) | ||||
|             this.#screen = Number(v) / this.#screenMax | ||||
|             this.notify("screen") | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +0,0 @@ | ||||
| { | ||||
|     "name": "astal-shell", | ||||
|     "dependencies": { | ||||
|         "astal": "/usr/share/astal/gjs" | ||||
|     } | ||||
| } | ||||
| @@ -1,23 +0,0 @@ | ||||
| // https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss | ||||
| $fg-color: #{"@theme_fg_color"}; | ||||
| $bg-color: #{"@theme_bg_color"}; | ||||
|  | ||||
| // Load stylesheet for notifications | ||||
| @use "./osd/OSD.scss"; | ||||
|  | ||||
| window.Bar { | ||||
|     background: transparent; | ||||
|     color: $fg-color; | ||||
|     font-weight: bold; | ||||
|  | ||||
|     >centerbox { | ||||
|         background: $bg-color; | ||||
|         border-radius: 10px; | ||||
|         margin: 8px; | ||||
|     } | ||||
|  | ||||
|     button { | ||||
|         border-radius: 8px; | ||||
|         margin: 2px; | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| { | ||||
|     "$schema": "https://json.schemastore.org/tsconfig", | ||||
|     "compilerOptions": { | ||||
|         "experimentalDecorators": true, | ||||
|         "strict": true, | ||||
|         "target": "ES2022", | ||||
|         "module": "ES2022", | ||||
|         "moduleResolution": "Bundler", | ||||
|         // "checkJs": true, | ||||
|         // "allowJs": true, | ||||
|         "jsx": "react-jsx", | ||||
|         "jsxImportSource": "astal/gtk3", | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user