diff options
Diffstat (limited to 'ags')
| -rw-r--r-- | ags/README.md | 15 | ||||
| -rw-r--r-- | ags/app.ts | 28 | ||||
| -rw-r--r-- | ags/config.js | 6 | ||||
| -rw-r--r-- | ags/env.d.ts | 21 | ||||
| -rw-r--r-- | ags/modules/applauncher.js | 107 | ||||
| -rw-r--r-- | ags/modules/bar.js | 131 | ||||
| -rw-r--r-- | ags/package.json | 6 | ||||
| -rw-r--r-- | ags/style.scss | 27 | ||||
| -rw-r--r-- | ags/tsconfig.json | 28 | ||||
| l--------- | ags/types | 1 | ||||
| -rw-r--r-- | ags/widget/Bar.tsx | 53 |
11 files changed, 144 insertions, 279 deletions
diff --git a/ags/README.md b/ags/README.md deleted file mode 100644 index 71563ed..0000000 --- a/ags/README.md +++ /dev/null @@ -1,15 +0,0 @@ - -# Starter Config - -if suggestions don't work, first make sure -you have TypeScript LSP working in your editor - -if you do not want typechecking only suggestions - -```json -// tsconfig.json -"checkJs": false -``` - -types are symlinked to: -/usr/share/com.github.Aylur.ags/types diff --git a/ags/app.ts b/ags/app.ts new file mode 100644 index 0000000..b485250 --- /dev/null +++ b/ags/app.ts @@ -0,0 +1,28 @@ +import { App } from "astal/gtk3" +import { exec } from "astal/process" + +import Bar from "./widget/Bar" + +function updateStyle() { + App.reset_css() + exec(`sass ./style.scss /tmp/style.css`) + App.apply_css("/tmp/style.css") +} + +App.start({ + requestHandler(request, res) { + switch (request) { + case "reload": + updateStyle() + res("style reloaded") + break; + default: + res("unknown command") + break; + } + }, + main() { + updateStyle() + App.get_monitors().map(Bar) + }, +}) diff --git a/ags/config.js b/ags/config.js deleted file mode 100644 index cc69e2e..0000000 --- a/ags/config.js +++ /dev/null @@ -1,6 +0,0 @@ -import { applauncher } from "./modules/applauncher.js" -import { Bar } from "./modules/bar.js" - -App.config({ - windows: [applauncher, Bar(0)], -}) diff --git a/ags/env.d.ts b/ags/env.d.ts new file mode 100644 index 0000000..467c0a4 --- /dev/null +++ b/ags/env.d.ts @@ -0,0 +1,21 @@ +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 +} diff --git a/ags/modules/applauncher.js b/ags/modules/applauncher.js deleted file mode 100644 index f380185..0000000 --- a/ags/modules/applauncher.js +++ /dev/null @@ -1,107 +0,0 @@ -const { query } = await Service.import("applications") -const WINDOW_NAME = "applauncher" - -/** @param {import('resource:///com/github/Aylur/ags/service/applications.js').Application} app */ -const AppItem = app => Widget.Button({ - on_clicked: () => { - App.closeWindow(WINDOW_NAME) - app.launch() - }, - attribute: { app }, - child: Widget.Box({ - children: [ - Widget.Icon({ - icon: app.icon_name || "", - size: 42, - }), - Widget.Label({ - class_name: "title", - label: app.name, - xalign: 0, - vpack: "center", - truncate: "end", - }), - ], - }), -}) - -const Applauncher = ({ width = 500, height = 500, spacing = 12 }) => { - // list of application buttons - let applications = query("").map(AppItem) - - // container holding the buttons - const list = Widget.Box({ - vertical: true, - children: applications, - spacing, - }) - - // repopulate the box, so the most frequent apps are on top of the list - function repopulate() { - applications = query("").map(AppItem) - list.children = applications - } - - // search entry - const entry = Widget.Entry({ - hexpand: true, - css: `margin-bottom: ${spacing}px;`, - - // to launch the first item on Enter - on_accept: () => { - // make sure we only consider visible (searched for) applications - const results = applications.filter((item) => item.visible); - if (results[0]) { - App.toggleWindow(WINDOW_NAME) - results[0].attribute.app.launch() - } - }, - - // filter out the list - on_change: ({ text }) => applications.forEach(item => { - item.visible = item.attribute.app.match(text ?? "") - }), - }) - - return Widget.Box({ - vertical: true, - css: `margin: ${spacing * 2}px;`, - children: [ - entry, - - // wrap the list in a scrollable - Widget.Scrollable({ - hscroll: "never", - css: `min-width: ${width}px;` - + `min-height: ${height}px;`, - child: list, - }), - ], - setup: self => self.hook(App, (_, windowName, visible) => { - if (windowName !== WINDOW_NAME) - return - - // when the applauncher shows up - if (visible) { - repopulate() - entry.text = "" - entry.grab_focus() - } - }), - }) -} - -// there needs to be only one instance -export const applauncher = Widget.Window({ - name: WINDOW_NAME, - setup: self => self.keybind("Escape", () => { - App.closeWindow(WINDOW_NAME) - }), - visible: false, - keymode: "exclusive", - child: Applauncher({ - width: 500, - height: 500, - spacing: 12, - }), -}) diff --git a/ags/modules/bar.js b/ags/modules/bar.js deleted file mode 100644 index 28fdaee..0000000 --- a/ags/modules/bar.js +++ /dev/null @@ -1,131 +0,0 @@ -const hyprland = await Service.import("hyprland") -const audio = await Service.import("audio") -const battery = await Service.import("battery") -const network = await Service.import("network") - -const hour = Variable("", { - poll: [60000, 'date "+%H:%M"'] -}) - -function IconLabel(icon, label) { - return [ - Widget.Icon({ icon }), - Widget.Label({ label }), - ] -} - -function Workspaces() { - const active = hyprland.active.workspace.bind("id") - const workspaces = hyprland.bind("workspaces") - .as(ws => ws.map(({ id }) => Widget.Button({ - on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`), - child: Widget.Label(`${id}`), - class_name: active.as(i => `${i === id ? "focused" : ""}`) - }))) - return Widget.Box({ - class_name: "workspaces", - children: workspaces, - }) -} - -//function SysTray() { -// -//} - -function Clock() { - return Widget.Label({ - class_name: "clock", - label: hour.bind(), - }) -} - -function Network() { - const label = network.wifi.bind("strength").as(s => ` ${s}`) - return Widget.Box({ - class_name: "network", - children: [ - Widget.Label({ label }) - ] - }) -} - -function Volume() { - const icons = { - 101: "overamplified", - 67: "high", - 34: "medium", - 1: "low", - 0: "muted", - } - function getIcon() { - const icon = audio.speaker.is_muted ? 0 : [101, 67, 34, 1, 0].find( - threshold => threshold <= audio.speaker.volume * 100) - - return `audio-volume-${icons[icon]}-symbolic` - } - - const icon = Utils.watch(getIcon(), audio.speaker, getIcon) - const label = audio.speaker.bind("volume").as(v => ` ${Math.floor(v * 100 + 0.01)}%`) - - return Widget.Box({ - class_name: "volume", - children: IconLabel(icon, label) - }) -} - -function Battery() { - const label = battery.bind("percent").as(p => ` ${p}%`) - const icon = battery.bind("percent").as(p => - `battery-level-${Math.floor(p / 10) * 10}-symbolic` - ) - - return Widget.Box({ - class_name: "battery", - children: IconLabel(icon, label) - }) -} - -function Left() { - return Widget.Box({ - spacing: 10, - children: [ - Workspaces(), - //SysTray(), - ] - }) -} -function Center() { - return Widget.Box({ - spacing: 10, - children: [ - Clock(), - ] - }) -} -function Right() { - return Widget.Box({ - hpack: "end", - spacing: 10, - children: [ - Network(), - Volume(), - Battery(), - ] - }) -} - -export function Bar(monitor = 0) { - return Widget.Window({ - name: `bar-${monitor}`, - class_name: "bar", - monitor, - anchor: ["top", "left", "right"], - exclusivity: "exclusive", - child: Widget.CenterBox({ - start_widget: Left(), - center_widget: Center(), - end_widget: Right(), - }), - }) -} - diff --git a/ags/package.json b/ags/package.json new file mode 100644 index 0000000..44226f2 --- /dev/null +++ b/ags/package.json @@ -0,0 +1,6 @@ +{ + "name": "astal-shell", + "dependencies": { + "astal": "/usr/share/astal/gjs" + } +} diff --git a/ags/style.scss b/ags/style.scss index df7b071..7ad03be 100644 --- a/ags/style.scss +++ b/ags/style.scss @@ -1,5 +1,26 @@ -$base-color: #c6538c; +// 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"}; -window { - background-color: $base-color; +window.Bar { + background: transparent; + color: $fg-color; + font-weight: bold; + + >centerbox { + background: $bg-color; + border-radius: 10px; + margin: 8px; + } + + >box { + background: $bg-color; + border-radius: 10px; + margin: 8px; + } + + button { + border-radius: 8px; + margin: 2px; + } } diff --git a/ags/tsconfig.json b/ags/tsconfig.json index 6860767..9471e35 100644 --- a/ags/tsconfig.json +++ b/ags/tsconfig.json @@ -1,18 +1,14 @@ { - "compilerOptions": { - "target": "ES2022", - "module": "ES2022", - "lib": [ - "ES2022" - ], - "allowJs": true, - "checkJs": true, - "strict": true, - "noImplicitAny": false, - "baseUrl": ".", - "typeRoots": [ - "./types" - ], - "skipLibCheck": true - } + "$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", + } } diff --git a/ags/types b/ags/types deleted file mode 120000 index a8e3f04..0000000 --- a/ags/types +++ /dev/null @@ -1 +0,0 @@ -/usr/share/com.github.Aylur.ags/types
\ No newline at end of file diff --git a/ags/widget/Bar.tsx b/ags/widget/Bar.tsx new file mode 100644 index 0000000..d994797 --- /dev/null +++ b/ags/widget/Bar.tsx @@ -0,0 +1,53 @@ +import { App, Astal, Gtk, Gdk, Widget } from "astal/gtk3" +import { Variable } from "astal" +import { BoxProps, CenterBoxProps } from "astal/gtk3/widget" + +const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor +const { START, CENTER, END } = Gtk.Align + +const time = Variable("").poll(1000, "date") + +function VerticalCenterBox(props: CenterBoxProps) { + return <centerbox + {...props} + vertical + /> +} + +function VerticalBox(props: BoxProps) { + return <box + {...props} + vertical + /> +} + +export default function Bar(gdkmonitor: Gdk.Monitor) { + return <window + name="Bar" + className="Bar" + gdkmonitor={gdkmonitor} + exclusivity={Astal.Exclusivity.EXCLUSIVE} + anchor={TOP | LEFT | BOTTOM} + application={App}> + <VerticalCenterBox> + <button + onClicked="echo hello" + halign={CENTER} + valign={START} + > + Welcome to AGS! + </button> + <VerticalBox> + <label>CIAO</label> + <label>CIAO</label> + </VerticalBox> + <button + onClicked={() => print("hello")} + halign={CENTER} + valign={END} + > + <label label={time()} /> + </button> + </VerticalCenterBox> + </window> +} |
