Implemented config changing functionality
This commit is contained in:
29
README.md
29
README.md
@@ -1,16 +1,15 @@
|
|||||||
Requirements:
|
|
||||||
```
|
# Starter Config
|
||||||
pipewire
|
|
||||||
bluez
|
if suggestions don't work, first make sure
|
||||||
bluez-utils
|
you have TypeScript LSP working in your editor
|
||||||
grimblast
|
|
||||||
gpu-screen-recorder
|
if you do not want typechecking only suggestions
|
||||||
hyprpicker
|
|
||||||
btop
|
```json
|
||||||
nmcli
|
// tsconfig.json
|
||||||
networkmanager
|
"checkJs": false
|
||||||
dart-sass
|
|
||||||
brightnessctl
|
|
||||||
python
|
|
||||||
python-gpustat
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
types are symlinked to:
|
||||||
|
/usr/share/com.github.Aylur.ags/types
|
||||||
|
|||||||
126
config.js
126
config.js
@@ -1,46 +1,92 @@
|
|||||||
import { exec } from "resource:///com/github/Aylur/ags/utils.js";
|
import GLib from "gi://GLib"
|
||||||
import { Bar, BarAlt } from "./modules/bar/index.js";
|
|
||||||
import DirectoryMonitorService from "./directoryMonitorService.js";
|
|
||||||
import MenuWindows from "./modules/menus/main.js";
|
|
||||||
import Notifications from "./modules/notifications/index.js";
|
|
||||||
|
|
||||||
const applyScss = () => {
|
const main = "/tmp/ags/hyprpanel/main.js"
|
||||||
// Compile scss
|
const entry = `${App.configDir}/main.ts`
|
||||||
exec(`sass ${App.configDir}/scss/main.scss ${App.configDir}/style.css`);
|
const bundler = GLib.getenv("AGS_BUNDLER") || "bun"
|
||||||
exec(
|
|
||||||
`sass ${App.configDir}/scss/highlight.scss ${App.configDir}/highlight.css`,
|
|
||||||
);
|
|
||||||
console.log("Scss compiled");
|
|
||||||
|
|
||||||
// Apply compiled css
|
const v = {
|
||||||
App.resetCss();
|
ags: pkg.version?.split(".").map(Number) || [],
|
||||||
App.applyCss(`${App.configDir}/style.css`);
|
expect: [1, 8, 1],
|
||||||
console.log("Compiled css applied");
|
}
|
||||||
};
|
|
||||||
|
|
||||||
DirectoryMonitorService.connect("changed", () => applyScss());
|
try {
|
||||||
|
switch (bundler) {
|
||||||
|
case "bun": await Utils.execAsync([
|
||||||
|
"bun", "build", entry,
|
||||||
|
"--outfile", main,
|
||||||
|
"--external", "resource://*",
|
||||||
|
"--external", "gi://*",
|
||||||
|
"--external", "file://*",
|
||||||
|
]); break
|
||||||
|
|
||||||
applyScss();
|
case "esbuild": await Utils.execAsync([
|
||||||
|
"esbuild", "--bundle", entry,
|
||||||
|
"--format=esm",
|
||||||
|
`--outfile=${main}`,
|
||||||
|
"--external:resource://*",
|
||||||
|
"--external:gi://*",
|
||||||
|
"--external:file://*",
|
||||||
|
]); break
|
||||||
|
|
||||||
const workspaceMonitorMap = {
|
default:
|
||||||
0: [4, 5],
|
throw `"${bundler}" is not a valid bundler`
|
||||||
1: [6, 7],
|
}
|
||||||
2: [1, 2, 3, 8, 9, 10],
|
|
||||||
};
|
|
||||||
|
|
||||||
App.config({
|
if (v.ags[1] < v.expect[1] || v.ags[2] < v.expect[2]) {
|
||||||
windows: [
|
print(`my config needs at least v${v.expect.join(".")}, yours is v${v.ags.join(".")}`)
|
||||||
...MenuWindows,
|
App.quit()
|
||||||
Notifications(),
|
}
|
||||||
BarAlt(0, workspaceMonitorMap),
|
|
||||||
BarAlt(1, workspaceMonitorMap),
|
await import(`file://${main}`)
|
||||||
Bar(2, workspaceMonitorMap),
|
} catch (error) {
|
||||||
],
|
console.error(error)
|
||||||
style: `${App.configDir}/style.css`,
|
App.quit()
|
||||||
closeWindowDelay: {
|
}
|
||||||
sideright: 350,
|
|
||||||
launcher: 350,
|
export { }
|
||||||
bar0: 350,
|
// import { exec } from "resource:///com/github/Aylur/ags/utils.js";
|
||||||
},
|
// import { Bar, BarAlt } from "./modules/bar/index.js";
|
||||||
onConfigParsed: () => Utils.execAsync(`python3 ${App.configDir}/services/bluetooth.py`),
|
// import DirectoryMonitorService from "./directoryMonitorService.js";
|
||||||
});
|
// import MenuWindows from "./modules/menus/main.js";
|
||||||
|
// import Notifications from "./modules/notifications/index.js";
|
||||||
|
//
|
||||||
|
// const applyScss = () => {
|
||||||
|
// // Compile scss
|
||||||
|
// exec(`sass ${App.configDir}/scss/main.scss ${App.configDir}/style.css`);
|
||||||
|
// exec(
|
||||||
|
// `sass ${App.configDir}/scss/highlight.scss ${App.configDir}/highlight.css`,
|
||||||
|
// );
|
||||||
|
// console.log("Scss compiled");
|
||||||
|
//
|
||||||
|
// // Apply compiled css
|
||||||
|
// App.resetCss();
|
||||||
|
// App.applyCss(`${App.configDir}/style.css`);
|
||||||
|
// console.log("Compiled css applied");
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// DirectoryMonitorService.connect("changed", () => applyScss());
|
||||||
|
//
|
||||||
|
// applyScss();
|
||||||
|
//
|
||||||
|
// const workspaceMonitorMap = {
|
||||||
|
// 0: [4, 5],
|
||||||
|
// 1: [6, 7],
|
||||||
|
// 2: [1, 2, 3, 8, 9, 10],
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// App.config({
|
||||||
|
// windows: [
|
||||||
|
// ...MenuWindows,
|
||||||
|
// Notifications(),
|
||||||
|
// BarAlt(0, workspaceMonitorMap),
|
||||||
|
// BarAlt(1, workspaceMonitorMap),
|
||||||
|
// Bar(2, workspaceMonitorMap),
|
||||||
|
// ],
|
||||||
|
// style: `${App.configDir}/style.css`,
|
||||||
|
// closeWindowDelay: {
|
||||||
|
// sideright: 350,
|
||||||
|
// launcher: 350,
|
||||||
|
// bar0: 350,
|
||||||
|
// },
|
||||||
|
// onConfigParsed: () => Utils.execAsync(`python3 ${App.configDir}/services/bluetooth.py`),
|
||||||
|
// });
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(globalThis, {
|
Object.assign(globalThis, {
|
||||||
OPTIONS: `${GLib.get_user_cache_dir()}/ags/options.json`,
|
OPTIONS: `${GLib.get_user_cache_dir()}/ags/hyprpanel/options.json`,
|
||||||
TMP: `${GLib.get_tmp_dir()}/asztal`,
|
TMP: `${GLib.get_tmp_dir()}/ags/hyprpanel`,
|
||||||
USER: GLib.get_user_name(),
|
USER: GLib.get_user_name(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
40
main.ts
Normal file
40
main.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { exec } from "resource:///com/github/Aylur/ags/utils.js";
|
||||||
|
import DirectoryMonitorService from "./directoryMonitorService.js";
|
||||||
|
import "lib/session"
|
||||||
|
import { Bar } from "modules/bar/Bar"
|
||||||
|
import MenuWindows from "./modules/menus/main.js";
|
||||||
|
import Notifications from "./modules/notifications/index.js";
|
||||||
|
import { forMonitors } from "lib/utils"
|
||||||
|
|
||||||
|
const applyScss = () => {
|
||||||
|
// Compile scss
|
||||||
|
exec(`sass ${App.configDir}/scss/main.scss ${App.configDir}/style.css`);
|
||||||
|
exec(
|
||||||
|
`sass ${App.configDir}/scss/highlight.scss ${App.configDir}/highlight.css`,
|
||||||
|
);
|
||||||
|
console.log("Scss compiled");
|
||||||
|
|
||||||
|
// Apply compiled css
|
||||||
|
App.resetCss();
|
||||||
|
App.applyCss(`${App.configDir}/style.css`);
|
||||||
|
console.log("Compiled css applied");
|
||||||
|
};
|
||||||
|
|
||||||
|
DirectoryMonitorService.connect("changed", () => applyScss());
|
||||||
|
|
||||||
|
applyScss();
|
||||||
|
|
||||||
|
App.config({
|
||||||
|
onConfigParsed: () => Utils.execAsync(`python3 ${App.configDir}/services/bluetooth.py`),
|
||||||
|
windows: [
|
||||||
|
...MenuWindows,
|
||||||
|
Notifications(),
|
||||||
|
...forMonitors(Bar),
|
||||||
|
],
|
||||||
|
style: `${App.configDir}/style.css`,
|
||||||
|
closeWindowDelay: {
|
||||||
|
sideright: 350,
|
||||||
|
launcher: 350,
|
||||||
|
bar0: 350,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
const network = await Service.import("network");
|
||||||
import { Menu } from "./menu/index.js";
|
import { Menu } from "./menu/index.js";
|
||||||
import { Workspaces } from "./workspaces/index.js";
|
import { Workspaces } from "./workspaces/index.js";
|
||||||
import { ClientTitle } from "./window_title/index.js";
|
import { ClientTitle } from "./window_title/index.js";
|
||||||
@@ -11,55 +12,71 @@ import { Clock } from "./clock/index.js";
|
|||||||
import { SysTray } from "./systray/index.js";
|
import { SysTray } from "./systray/index.js";
|
||||||
|
|
||||||
import { BarItemBox as WidgetContainer } from "../shared/barItemBox.js";
|
import { BarItemBox as WidgetContainer } from "../shared/barItemBox.js";
|
||||||
import options from "options"
|
import options from "options";
|
||||||
|
|
||||||
const { start, center, end } = options.bar.layout
|
const { start, center, end } = options.bar.layout;
|
||||||
const { transparent, position } = options.bar
|
const { transparent, position } = options.bar;
|
||||||
|
|
||||||
export type BarWidget = keyof typeof widget
|
export type BarWidget = keyof typeof widget;
|
||||||
|
|
||||||
const widget = {
|
const widget = {
|
||||||
battery: WidgetContainer(BatteryLabel()),
|
battery: () => WidgetContainer(BatteryLabel()),
|
||||||
dashboard: WidgetContainer(Menu()),
|
dashboard: () => WidgetContainer(Menu()),
|
||||||
workspaces: WidgetContainer(Workspaces()),
|
workspaces: (monitor) => WidgetContainer(Workspaces(monitor, 10)),
|
||||||
windowtitle: WidgetContainer(ClientTitle()),
|
windowtitle: () => WidgetContainer(ClientTitle()),
|
||||||
media: WidgetContainer(Media()),
|
media: () => WidgetContainer(Media()),
|
||||||
notifications: WidgetContainer(Notifications()),
|
notifications: () => WidgetContainer(Notifications()),
|
||||||
volume: WidgetContainer(Volume()),
|
volume: () => WidgetContainer(Volume()),
|
||||||
network: WidgetContainer(Network()),
|
network: () => WidgetContainer(Network()),
|
||||||
bluetooth: WidgetContainer(Bluetooth()),
|
bluetooth: () => WidgetContainer(Bluetooth()),
|
||||||
clock: WidgetContainer(Clock()),
|
clock: () => WidgetContainer(Clock()),
|
||||||
systray: WidgetContainer(SysTray()),
|
systray: () => WidgetContainer(SysTray()),
|
||||||
// expander: () => Widget.Box({ expand: true }),
|
// expander: () => Widget.Box({ expand: true }),
|
||||||
}
|
};
|
||||||
|
|
||||||
export const Bar = (monitor: number) => Widget.Window({
|
export const Bar = (monitor: number) => {
|
||||||
monitor,
|
return Widget.Window({
|
||||||
|
name: `bar-${monitor}`,
|
||||||
class_name: "bar",
|
class_name: "bar",
|
||||||
name: `bar${monitor}`,
|
monitor,
|
||||||
|
visible: true,
|
||||||
|
anchor: ["top", "left", "right"],
|
||||||
exclusivity: "exclusive",
|
exclusivity: "exclusive",
|
||||||
anchor: position.bind().as(pos => [pos, "right", "left"]),
|
|
||||||
child: Widget.CenterBox({
|
child: Widget.CenterBox({
|
||||||
startWidget: Widget.Box({
|
visible: true,
|
||||||
class_name: "box-left",
|
startWidget: Widget.Box({
|
||||||
spacing: 5,
|
class_name: "box-left",
|
||||||
hexpand: true,
|
spacing: 5,
|
||||||
children: start.bind().as(s => s.map(w => widget[w])),
|
hexpand: true,
|
||||||
}),
|
setup: self => {
|
||||||
centerWidget: Widget.Box({
|
self.children = start.value.map(w => widget[w](monitor));
|
||||||
class_name: "box-center",
|
self.hook(start, (self) => {
|
||||||
hpack: "center",
|
self.children = start.value.map(w => widget[w](monitor));
|
||||||
spacing: 5,
|
})
|
||||||
children: center.bind().as(c => c.map(w => widget[w])),
|
},
|
||||||
}),
|
}),
|
||||||
endWidget: Widget.Box({
|
centerWidget: Widget.Box({
|
||||||
class_name: "box-right",
|
class_name: "box-center",
|
||||||
hexpand: true,
|
hpack: "center",
|
||||||
spacing: 5,
|
spacing: 5,
|
||||||
children: end.bind().as(e => e.map(w => widget[w])),
|
setup: self => {
|
||||||
}),
|
self.children = center.value.map(w => widget[w](monitor));
|
||||||
}),
|
self.hook(center, (self) => {
|
||||||
setup: self => self.hook(transparent, () => {
|
self.children = center.value.map(w => widget[w](monitor));
|
||||||
self.toggleClassName("transparent", transparent.value)
|
})
|
||||||
}),
|
},
|
||||||
})
|
}),
|
||||||
|
endWidget: Widget.Box({
|
||||||
|
class_name: "box-right",
|
||||||
|
hpack: "end",
|
||||||
|
spacing: 5,
|
||||||
|
setup: self => {
|
||||||
|
self.children = end.value.map(w => widget[w](monitor));
|
||||||
|
self.hook(end, (self) => {
|
||||||
|
self.children = end.value.map(w => widget[w](monitor));
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,14 +6,11 @@ export const Notifications = () => {
|
|||||||
return {
|
return {
|
||||||
component: Widget.Box({
|
component: Widget.Box({
|
||||||
hpack: "start",
|
hpack: "start",
|
||||||
hexpand: true,
|
child: Widget.Box({
|
||||||
child: Widget.Button({
|
|
||||||
hpack: "start",
|
hpack: "start",
|
||||||
hexpand: true,
|
|
||||||
class_name: "bar-notifications",
|
class_name: "bar-notifications",
|
||||||
child: Widget.Label({
|
child: Widget.Label({
|
||||||
hpack: "center",
|
hpack: "center",
|
||||||
hexpand: true,
|
|
||||||
class_name: "bar-notifications-label",
|
class_name: "bar-notifications-label",
|
||||||
setup: (self) => {
|
setup: (self) => {
|
||||||
self.hook(notifs, () => {
|
self.hook(notifs, () => {
|
||||||
|
|||||||
@@ -1,49 +1,81 @@
|
|||||||
const hyprland = await Service.import("hyprland");
|
const hyprland = await Service.import("hyprland");
|
||||||
|
import options from "options";
|
||||||
|
|
||||||
|
const { workspaces, monitorSpecific } = options.bar.workspaces;
|
||||||
|
|
||||||
function range(length, start = 1) {
|
function range(length, start = 1) {
|
||||||
return Array.from({ length }, (_, i) => i + start);
|
return Array.from({ length }, (_, i) => i + start);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Workspaces = (monitor = -1, wsMap = {}, ws = 8) => {
|
const Workspaces = (monitor = -1, ws = 8) => {
|
||||||
const getWorkspacesForMonitor = (curWs) => {
|
const getWorkspacesForMonitor = (curWs, wsRules) => {
|
||||||
if (
|
const monitorMap = {};
|
||||||
Object.keys(wsMap)
|
hyprland.monitors.forEach((m) => (monitorMap[m.id] = m.name));
|
||||||
.map((mn) => Number(mn))
|
|
||||||
.includes(monitor)
|
const currentMonitorName = monitorMap[monitor];
|
||||||
) {
|
return wsRules[currentMonitorName].includes(curWs);
|
||||||
return wsMap[monitor].includes(curWs);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getWorkspaceRules = () => {
|
||||||
|
try {
|
||||||
|
const rules = Utils.exec("hyprctl workspacerules -j");
|
||||||
|
|
||||||
|
const workspaceRules = {};
|
||||||
|
|
||||||
|
JSON.parse(rules).forEach((rule, index) => {
|
||||||
|
if (Object.hasOwnProperty.call(workspaceRules, rule.monitor)) {
|
||||||
|
workspaceRules[rule.monitor].push(index + 1);
|
||||||
|
} else {
|
||||||
|
workspaceRules[rule.monitor] = [index + 1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return workspaceRules;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
component: Widget.Box({
|
component: Widget.Box({
|
||||||
class_name: "workspaces",
|
class_name: "workspaces",
|
||||||
children: range(ws || 8)
|
children: Utils.merge(
|
||||||
.filter((i) => getWorkspacesForMonitor(i))
|
[workspaces.bind(), monitorSpecific.bind()],
|
||||||
.map((i) => {
|
(workspaces, monitorSpecific) => {
|
||||||
return Widget.Label({
|
return range(workspaces || 8)
|
||||||
attribute: i,
|
.filter((i) => {
|
||||||
vpack: "center",
|
if (!monitorSpecific) {
|
||||||
label: `${i}`,
|
return true;
|
||||||
setup: (self) =>
|
}
|
||||||
self.hook(hyprland, () => {
|
const workspaceRules = getWorkspaceRules();
|
||||||
self.toggleClassName(
|
return getWorkspacesForMonitor(i, workspaceRules);
|
||||||
"active",
|
})
|
||||||
hyprland.active.workspace.id === i,
|
.map((i) => {
|
||||||
);
|
return Widget.Label({
|
||||||
self.toggleClassName(
|
attribute: i,
|
||||||
"occupied",
|
vpack: "center",
|
||||||
(hyprland.getWorkspace(i)?.windows || 0) > 0,
|
label: `${i}`,
|
||||||
);
|
setup: (self) =>
|
||||||
|
self.hook(hyprland, () => {
|
||||||
|
self.toggleClassName(
|
||||||
|
"active",
|
||||||
|
hyprland.active.workspace.id === i,
|
||||||
|
);
|
||||||
|
self.toggleClassName(
|
||||||
|
"occupied",
|
||||||
|
(hyprland.getWorkspace(i)?.windows || 0) > 0,
|
||||||
|
);
|
||||||
|
|
||||||
const isCurrentMonitor =
|
const isCurrentMonitor =
|
||||||
monitor !== -1 &&
|
monitor !== -1 &&
|
||||||
hyprland.getWorkspace(i)?.monitorID !== monitor;
|
hyprland.getWorkspace(i)?.monitorID !== monitor;
|
||||||
|
|
||||||
self.toggleClassName("hidden", isCurrentMonitor);
|
self.toggleClassName("hidden", isCurrentMonitor);
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
setup: (box) => {
|
setup: (box) => {
|
||||||
if (ws === 0) {
|
if (ws === 0) {
|
||||||
box.hook(hyprland.active.workspace, () =>
|
box.hook(hyprland.active.workspace, () =>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ export const BarItemBox = (child) => {
|
|||||||
if (Object.hasOwnProperty.call(child, "isVis")) {
|
if (Object.hasOwnProperty.call(child, "isVis")) {
|
||||||
return child.isVis.bind("value");
|
return child.isVis.bind("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
return child.isVisible;
|
return child.isVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
37
options.ts
37
options.ts
@@ -7,37 +7,17 @@ const options = mkOptions(OPTIONS, {
|
|||||||
autotheme: opt(false),
|
autotheme: opt(false),
|
||||||
|
|
||||||
theme: {
|
theme: {
|
||||||
dark: {
|
primary: {
|
||||||
primary: {
|
bg: opt("#51a4e7"),
|
||||||
bg: opt("#51a4e7"),
|
fg: opt("#141414"),
|
||||||
fg: opt("#141414"),
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
bg: opt("#e55f86"),
|
|
||||||
fg: opt("#141414"),
|
|
||||||
},
|
|
||||||
bg: opt("#171717"),
|
|
||||||
fg: opt("#eeeeee"),
|
|
||||||
widget: opt("#eeeeee"),
|
|
||||||
border: opt("#eeeeee"),
|
|
||||||
},
|
},
|
||||||
light: {
|
error: {
|
||||||
primary: {
|
bg: opt("#e55f86"),
|
||||||
bg: opt("#426ede"),
|
fg: opt("#141414"),
|
||||||
fg: opt("#eeeeee"),
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
bg: opt("#b13558"),
|
|
||||||
fg: opt("#eeeeee"),
|
|
||||||
},
|
|
||||||
bg: opt("#fffffa"),
|
|
||||||
fg: opt("#080808"),
|
|
||||||
widget: opt("#080808"),
|
|
||||||
border: opt("#080808"),
|
|
||||||
},
|
},
|
||||||
|
bg: opt("#171717"),
|
||||||
|
fg: opt("#eeeeee"),
|
||||||
blur: opt(0),
|
blur: opt(0),
|
||||||
scheme: opt<"dark" | "light">("dark"),
|
|
||||||
widget: { opacity: opt(94) },
|
widget: { opacity: opt(94) },
|
||||||
border: {
|
border: {
|
||||||
width: opt(1),
|
width: opt(1),
|
||||||
@@ -97,6 +77,7 @@ const options = mkOptions(OPTIONS, {
|
|||||||
},
|
},
|
||||||
workspaces: {
|
workspaces: {
|
||||||
workspaces: opt(7),
|
workspaces: opt(7),
|
||||||
|
monitorSpecific: opt(true),
|
||||||
},
|
},
|
||||||
taskbar: {
|
taskbar: {
|
||||||
iconSize: opt(0),
|
iconSize: opt(0),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"lib": [
|
"lib": [
|
||||||
|
|||||||
Reference in New Issue
Block a user