feat: define bar layout via config
This commit is contained in:
parent
473e5a6b8a
commit
579070733c
5 changed files with 172 additions and 136 deletions
|
|
@ -280,7 +280,7 @@
|
||||||
margin-right: -1px;
|
margin-right: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.power {
|
.last {
|
||||||
padding-right: lib.s(12);
|
padding-right: lib.s(12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,11 +304,11 @@
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.os-icon {
|
.first {
|
||||||
padding-top: lib.s(12);
|
padding-top: lib.s(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.power {
|
.last {
|
||||||
padding-bottom: lib.s(12);
|
padding-bottom: lib.s(12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,43 +10,44 @@ export default {
|
||||||
bar: {
|
bar: {
|
||||||
vertical: true,
|
vertical: true,
|
||||||
style: "gaps", // One of "gaps", "panel", "embedded"
|
style: "gaps", // One of "gaps", "panel", "embedded"
|
||||||
|
layout: {
|
||||||
|
type: "centerbox", // One of "centerbox", "flowbox"
|
||||||
|
centerbox: {
|
||||||
|
start: ["osIcon", "activeWindow", "mediaPlaying", "brightnessSpacer"],
|
||||||
|
center: ["workspaces"],
|
||||||
|
end: [
|
||||||
|
"volumeSpacer",
|
||||||
|
"tray",
|
||||||
|
"statusIcons",
|
||||||
|
"pkgUpdates",
|
||||||
|
"notifCount",
|
||||||
|
"battery",
|
||||||
|
"dateTime",
|
||||||
|
"power",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
flowbox: [
|
||||||
|
"osIcon",
|
||||||
|
"workspaces",
|
||||||
|
"brightnessSpacer",
|
||||||
|
"activeWindow",
|
||||||
|
"volumeSpacer",
|
||||||
|
"dateTime",
|
||||||
|
"tray",
|
||||||
|
"battery",
|
||||||
|
"statusIcons",
|
||||||
|
"notifCount",
|
||||||
|
"power",
|
||||||
|
],
|
||||||
|
},
|
||||||
modules: {
|
modules: {
|
||||||
osIcon: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
activeWindow: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
mediaPlaying: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
workspaces: {
|
workspaces: {
|
||||||
enabled: true,
|
|
||||||
shown: 5,
|
shown: 5,
|
||||||
},
|
},
|
||||||
tray: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
statusIcons: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
pkgUpdates: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
notifCount: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
battery: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
dateTime: {
|
dateTime: {
|
||||||
enabled: true,
|
|
||||||
format: "%d/%m/%y %R",
|
format: "%d/%m/%y %R",
|
||||||
detailedFormat: "%c",
|
detailedFormat: "%c",
|
||||||
},
|
},
|
||||||
power: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
launcher: {
|
launcher: {
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,20 @@ const isCorrectType = (v: any, type: string | string[] | number[], path: string)
|
||||||
try {
|
try {
|
||||||
// Recursively check type
|
// Recursively check type
|
||||||
const type = JSON.parse(arrType);
|
const type = JSON.parse(arrType);
|
||||||
const valid = v.filter((item, i) =>
|
if (Array.isArray(type)) {
|
||||||
Object.entries(type).some(([k, t]) => {
|
v.splice(0, v.length, ...v.filter((item, i) => isCorrectType(item, type, `${path}[${i}]`)));
|
||||||
if (!item[k]) {
|
} else {
|
||||||
console.warn(`Invalid shape for ${path}[${i}]: ${JSON.stringify(item)} != ${arrType}`);
|
const valid = v.filter((item, i) =>
|
||||||
return false;
|
Object.entries(type).some(([k, t]) => {
|
||||||
}
|
if (!item[k]) {
|
||||||
return !isCorrectType(item[k], t as any, `${path}[${i}].${k}`);
|
console.warn(`Invalid shape for ${path}[${i}]: ${JSON.stringify(item)} != ${arrType}`);
|
||||||
})
|
return false;
|
||||||
);
|
}
|
||||||
v.splice(0, v.length, ...valid); // In-place filter
|
return !isCorrectType(item[k], t as any, `${path}[${i}].${k}`);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
v.splice(0, v.length, ...valid); // In-place filter
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
const valid = v.filter((item, i) => {
|
const valid = v.filter((item, i) => {
|
||||||
if (typeof item !== arrType) {
|
if (typeof item !== arrType) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,25 @@
|
||||||
const BOOL = "boolean";
|
const BOOL = "boolean";
|
||||||
const STR = "string";
|
const STR = "string";
|
||||||
const NUM = "number";
|
const NUM = "number";
|
||||||
const ARR = (type: string) => `array of ${type}`;
|
const ARR = (type: string | string[]) => `array of ${typeof type === "string" ? type : JSON.stringify(type)}`;
|
||||||
const OBJ_ARR = (shape: object) => ARR(JSON.stringify(shape));
|
const OBJ_ARR = (shape: object) => ARR(JSON.stringify(shape));
|
||||||
|
|
||||||
|
const barModules = [
|
||||||
|
"osIcon",
|
||||||
|
"activeWindow",
|
||||||
|
"mediaPlaying",
|
||||||
|
"brightnessSpacer",
|
||||||
|
"workspaces",
|
||||||
|
"volumeSpacer",
|
||||||
|
"tray",
|
||||||
|
"statusIcons",
|
||||||
|
"pkgUpdates",
|
||||||
|
"notifCount",
|
||||||
|
"battery",
|
||||||
|
"dateTime",
|
||||||
|
"power",
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
"style.transparency": ["off", "normal", "high"],
|
"style.transparency": ["off", "normal", "high"],
|
||||||
"style.borders": BOOL,
|
"style.borders": BOOL,
|
||||||
|
|
@ -11,20 +27,14 @@ export default {
|
||||||
// Bar
|
// Bar
|
||||||
"bar.vertical": BOOL,
|
"bar.vertical": BOOL,
|
||||||
"bar.style": ["gaps", "panel", "embedded"],
|
"bar.style": ["gaps", "panel", "embedded"],
|
||||||
"bar.modules.osIcon.enabled": BOOL,
|
"bar.layout.type": ["centerbox", "flowbox"],
|
||||||
"bar.modules.activeWindow.enabled": BOOL,
|
"bar.layout.centerbox.start": ARR(barModules),
|
||||||
"bar.modules.mediaPlaying.enabled": BOOL,
|
"bar.layout.centerbox.center": ARR(barModules),
|
||||||
"bar.modules.workspaces.enabled": BOOL,
|
"bar.layout.centerbox.end": ARR(barModules),
|
||||||
|
"bar.layout.flowbox": ARR(barModules),
|
||||||
"bar.modules.workspaces.shown": NUM,
|
"bar.modules.workspaces.shown": NUM,
|
||||||
"bar.modules.tray.enabled": BOOL,
|
|
||||||
"bar.modules.statusIcons.enabled": BOOL,
|
|
||||||
"bar.modules.pkgUpdates.enabled": BOOL,
|
|
||||||
"bar.modules.notifCount.enabled": BOOL,
|
|
||||||
"bar.modules.battery.enabled": BOOL,
|
|
||||||
"bar.modules.dateTime.enabled": BOOL,
|
|
||||||
"bar.modules.dateTime.format": STR,
|
"bar.modules.dateTime.format": STR,
|
||||||
"bar.modules.dateTime.detailedFormat": STR,
|
"bar.modules.dateTime.detailedFormat": STR,
|
||||||
"bar.modules.power.enabled": BOOL,
|
|
||||||
// Launcher
|
// Launcher
|
||||||
"launcher.style": ["lines", "round"],
|
"launcher.style": ["lines", "round"],
|
||||||
"launcher.actionPrefix": STR,
|
"launcher.actionPrefix": STR,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { setupCustomTooltip } from "@/utils/widgets";
|
||||||
import ScreenCorner from "@/widgets/screencorner";
|
import ScreenCorner from "@/widgets/screencorner";
|
||||||
import { execAsync, Variable } from "astal";
|
import { execAsync, Variable } from "astal";
|
||||||
import { bind, kebabify } from "astal/binding";
|
import { bind, kebabify } from "astal/binding";
|
||||||
import { App, Astal, Gtk, type Widget } from "astal/gtk3";
|
import { App, Astal, Gtk, Widget } from "astal/gtk3";
|
||||||
import { bar as config } from "config";
|
import { bar as config } from "config";
|
||||||
import AstalBattery from "gi://AstalBattery";
|
import AstalBattery from "gi://AstalBattery";
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
|
|
@ -20,12 +20,14 @@ import AstalNotifd from "gi://AstalNotifd";
|
||||||
import AstalTray from "gi://AstalTray";
|
import AstalTray from "gi://AstalTray";
|
||||||
import AstalWp from "gi://AstalWp";
|
import AstalWp from "gi://AstalWp";
|
||||||
|
|
||||||
interface SpacerClassNameProps {
|
interface ClassNameProps {
|
||||||
beforeSpacer?: boolean;
|
beforeSpacer: boolean;
|
||||||
afterSpacer?: boolean;
|
afterSpacer: boolean;
|
||||||
|
first: boolean;
|
||||||
|
last: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ModuleProps extends SpacerClassNameProps {
|
interface ModuleProps extends ClassNameProps {
|
||||||
monitor: Monitor;
|
monitor: Monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,13 +85,33 @@ const switchPane = (monitor: Monitor, name: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const spacerClassName = ({ beforeSpacer, afterSpacer }: SpacerClassNameProps) =>
|
const getClassName = ({ beforeSpacer, afterSpacer, first, last }: ClassNameProps) =>
|
||||||
`${beforeSpacer ? "before-spacer" : ""} ${afterSpacer ? "after-spacer" : ""}`;
|
`${beforeSpacer ? "before-spacer" : ""} ${afterSpacer ? "after-spacer" : ""}` +
|
||||||
|
` ${first ? "first" : ""} ${last ? "last" : ""}`;
|
||||||
|
|
||||||
|
const getModule = (module: string) => {
|
||||||
|
module = module.toLowerCase();
|
||||||
|
if (module === "osicon") return OSIcon;
|
||||||
|
if (module === "activewindow") return ActiveWindow;
|
||||||
|
if (module === "mediaplaying") return MediaPlaying;
|
||||||
|
if (module === "workspaces") return Workspaces;
|
||||||
|
if (module === "tray") return Tray;
|
||||||
|
if (module === "statusicons") return StatusIcons;
|
||||||
|
if (module === "pkgupdates") return PkgUpdates;
|
||||||
|
if (module === "notifcount") return NotifCount;
|
||||||
|
if (module === "battery") return Battery;
|
||||||
|
if (module === "datetime") return DateTime;
|
||||||
|
if (module === "power") return Power;
|
||||||
|
if (module === "brightnessspacer") return BrightnessSpacer;
|
||||||
|
if (module === "volumespacer") return VolumeSpacer;
|
||||||
|
return () => null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSpacer = (module?: string) => module?.toLowerCase().endsWith("spacer") ?? false;
|
||||||
|
|
||||||
const OSIcon = ({ monitor, ...props }: ModuleProps) => (
|
const OSIcon = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.osIcon.enabled)}
|
className={`module os-icon ${getClassName(props)}`}
|
||||||
className={`module os-icon ${spacerClassName(props)}`}
|
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "dashboard")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "dashboard")}
|
||||||
>
|
>
|
||||||
{osIcon}
|
{osIcon}
|
||||||
|
|
@ -98,9 +120,8 @@ const OSIcon = ({ monitor, ...props }: ModuleProps) => (
|
||||||
|
|
||||||
const ActiveWindow = ({ monitor, ...props }: ModuleProps) => (
|
const ActiveWindow = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<box
|
<box
|
||||||
visible={bind(config.modules.activeWindow.enabled)}
|
|
||||||
vertical={bind(config.vertical)}
|
vertical={bind(config.vertical)}
|
||||||
className={`module active-window ${spacerClassName(props)}`}
|
className={`module active-window ${getClassName(props)}`}
|
||||||
setup={self => {
|
setup={self => {
|
||||||
const title = Variable("");
|
const title = Variable("");
|
||||||
const updateTooltip = (c: AstalHyprland.Client | null) =>
|
const updateTooltip = (c: AstalHyprland.Client | null) =>
|
||||||
|
|
@ -144,7 +165,6 @@ const MediaPlaying = ({ monitor, ...props }: ModuleProps) => {
|
||||||
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
|
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.mediaPlaying.enabled)}
|
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "audio");
|
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "audio");
|
||||||
else if (event.button === Astal.MouseButton.SECONDARY) players.lastPlayer?.play_pause();
|
else if (event.button === Astal.MouseButton.SECONDARY) players.lastPlayer?.play_pause();
|
||||||
|
|
@ -156,7 +176,7 @@ const MediaPlaying = ({ monitor, ...props }: ModuleProps) => {
|
||||||
setupCustomTooltip(self, bind(label));
|
setupCustomTooltip(self, bind(label));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<box vertical={bind(config.vertical)} className={`module media-playing ${spacerClassName(props)}`}>
|
<box vertical={bind(config.vertical)} className={`module media-playing ${getClassName(props)}`}>
|
||||||
<icon
|
<icon
|
||||||
setup={self =>
|
setup={self =>
|
||||||
players.hookLastPlayer(self, "notify::identity", () => {
|
players.hookLastPlayer(self, "notify::identity", () => {
|
||||||
|
|
@ -228,7 +248,6 @@ const Workspace = ({ idx }: { idx: number }) => {
|
||||||
|
|
||||||
const Workspaces = ({ monitor, ...props }: ModuleProps) => (
|
const Workspaces = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<eventbox
|
<eventbox
|
||||||
visible={bind(config.modules.workspaces.enabled)}
|
|
||||||
onScroll={(_, event) => {
|
onScroll={(_, event) => {
|
||||||
const activeWs = hyprland.focusedClient?.workspace.name;
|
const activeWs = hyprland.focusedClient?.workspace.name;
|
||||||
if (activeWs?.startsWith("special:")) hyprland.dispatch("togglespecialworkspace", activeWs.slice(8));
|
if (activeWs?.startsWith("special:")) hyprland.dispatch("togglespecialworkspace", activeWs.slice(8));
|
||||||
|
|
@ -236,7 +255,7 @@ const Workspaces = ({ monitor, ...props }: ModuleProps) => (
|
||||||
hyprland.dispatch("workspace", (event.delta_y < 0 ? "-" : "+") + 1);
|
hyprland.dispatch("workspace", (event.delta_y < 0 ? "-" : "+") + 1);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<box vertical={bind(config.vertical)} className={`module workspaces ${spacerClassName(props)}`}>
|
<box vertical={bind(config.vertical)} className={`module workspaces ${getClassName(props)}`}>
|
||||||
{bind(config.modules.workspaces.shown).as(
|
{bind(config.modules.workspaces.shown).as(
|
||||||
n => Array.from({ length: n }).map((_, idx) => <Workspace idx={idx + 1} />) // Start from 1
|
n => Array.from({ length: n }).map((_, idx) => <Workspace idx={idx + 1} />) // Start from 1
|
||||||
)}
|
)}
|
||||||
|
|
@ -257,25 +276,17 @@ const TrayItem = (item: AstalTray.TrayItem) => (
|
||||||
</menubutton>
|
</menubutton>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Tray = ({ monitor, ...props }: ModuleProps) => {
|
const Tray = ({ monitor, ...props }: ModuleProps) => (
|
||||||
const visible = Variable.derive(
|
<box
|
||||||
[config.modules.tray.enabled, bind(AstalTray.get_default(), "items")],
|
visible={bind(AstalTray.get_default(), "items").as(i => i.length > 0)}
|
||||||
(e, i) => e && i.length > 0
|
vertical={bind(config.vertical)}
|
||||||
);
|
className={`module tray ${getClassName(props)}`}
|
||||||
|
>
|
||||||
|
{bind(AstalTray.get_default(), "items").as(i => i.map(TrayItem))}
|
||||||
|
</box>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
const Network = ({ monitor }: { monitor: Monitor }) => (
|
||||||
<box
|
|
||||||
visible={bind(visible)}
|
|
||||||
vertical={bind(config.vertical)}
|
|
||||||
className={`module tray ${spacerClassName(props)}`}
|
|
||||||
onDestroy={() => visible.drop()}
|
|
||||||
>
|
|
||||||
{bind(AstalTray.get_default(), "items").as(i => i.map(TrayItem))}
|
|
||||||
</box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Network = () => (
|
|
||||||
<button
|
<button
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
const network = AstalNetwork.get_default();
|
const network = AstalNetwork.get_default();
|
||||||
|
|
@ -378,7 +389,7 @@ const Network = () => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const BluetoothDevice = (device: AstalBluetooth.Device) => (
|
const BluetoothDevice = ({ monitor, device }: { monitor: Monitor; device: AstalBluetooth.Device }) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(device, "connected")}
|
visible={bind(device, "connected")}
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
|
|
@ -398,7 +409,7 @@ const BluetoothDevice = (device: AstalBluetooth.Device) => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Bluetooth = () => (
|
const Bluetooth = ({ monitor }: { monitor: Monitor }) => (
|
||||||
<box vertical={bind(config.vertical)} className="bluetooth">
|
<box vertical={bind(config.vertical)} className="bluetooth">
|
||||||
<button
|
<button
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
|
|
@ -440,24 +451,21 @@ const Bluetooth = () => (
|
||||||
<label className="icon" label="bluetooth_disabled" name="disabled" />
|
<label className="icon" label="bluetooth_disabled" name="disabled" />
|
||||||
</stack>
|
</stack>
|
||||||
</button>
|
</button>
|
||||||
{bind(AstalBluetooth.get_default(), "devices").as(d => d.map(BluetoothDevice))}
|
{bind(AstalBluetooth.get_default(), "devices").as(d =>
|
||||||
|
d.map(d => <BluetoothDevice monitor={monitor} device={d} />)
|
||||||
|
)}
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const StatusIcons = ({ monitor, ...props }: ModuleProps) => (
|
const StatusIcons = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<box
|
<box vertical={bind(config.vertical)} className={`module status-icons ${getClassName(props)}`}>
|
||||||
visible={bind(config.modules.statusIcons.enabled)}
|
<Network monitor={monitor} />
|
||||||
vertical={bind(config.vertical)}
|
<Bluetooth monitor={monitor} />
|
||||||
className={`module status-icons ${spacerClassName(props)}`}
|
|
||||||
>
|
|
||||||
<Network />
|
|
||||||
<Bluetooth />
|
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.pkgUpdates.enabled)}
|
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "packages")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "packages")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(
|
setupCustomTooltip(
|
||||||
|
|
@ -466,7 +474,7 @@ const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<box vertical={bind(config.vertical)} className={`module pkg-updates ${spacerClassName(props)}`}>
|
<box vertical={bind(config.vertical)} className={`module pkg-updates ${getClassName(props)}`}>
|
||||||
<label className="icon" label="download" />
|
<label className="icon" label="download" />
|
||||||
<label label={bind(Updates.get_default(), "numUpdates").as(String)} />
|
<label label={bind(Updates.get_default(), "numUpdates").as(String)} />
|
||||||
</box>
|
</box>
|
||||||
|
|
@ -475,7 +483,6 @@ const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
||||||
|
|
||||||
const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.notifCount.enabled)}
|
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "notifpane")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "notifpane")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(
|
setupCustomTooltip(
|
||||||
|
|
@ -486,7 +493,7 @@ const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<box vertical={bind(config.vertical)} className={`module notif-count ${spacerClassName(props)}`}>
|
<box vertical={bind(config.vertical)} className={`module notif-count ${getClassName(props)}`}>
|
||||||
<label
|
<label
|
||||||
className="icon"
|
className="icon"
|
||||||
label={bind(AstalNotifd.get_default(), "dontDisturb").as(d => (d ? "notifications_off" : "info"))}
|
label={bind(AstalNotifd.get_default(), "dontDisturb").as(d => (d ? "notifications_off" : "info"))}
|
||||||
|
|
@ -505,13 +512,9 @@ const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
const Battery = ({ monitor, ...props }: ModuleProps) => {
|
const Battery = ({ monitor, ...props }: ModuleProps) => {
|
||||||
const visible = Variable.derive(
|
|
||||||
[config.modules.battery.enabled, bind(AstalBattery.get_default(), "isBattery")],
|
|
||||||
(e, i) => e && i
|
|
||||||
);
|
|
||||||
const className = Variable.derive(
|
const className = Variable.derive(
|
||||||
[bind(AstalBattery.get_default(), "percentage"), bind(AstalBattery.get_default(), "charging")],
|
[bind(AstalBattery.get_default(), "percentage"), bind(AstalBattery.get_default(), "charging")],
|
||||||
(p, c) => `module battery ${c ? "charging" : p < 0.2 ? "low" : ""} ${spacerClassName(props)}`
|
(p, c) => `module battery ${c ? "charging" : p < 0.2 ? "low" : ""} ${getClassName(props)}`
|
||||||
);
|
);
|
||||||
const tooltip = Variable.derive(
|
const tooltip = Variable.derive(
|
||||||
[bind(AstalBattery.get_default(), "timeToEmpty"), bind(AstalBattery.get_default(), "timeToFull")],
|
[bind(AstalBattery.get_default(), "timeToEmpty"), bind(AstalBattery.get_default(), "timeToFull")],
|
||||||
|
|
@ -520,12 +523,11 @@ const Battery = ({ monitor, ...props }: ModuleProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<box
|
<box
|
||||||
visible={bind(visible)}
|
visible={bind(AstalBattery.get_default(), "isBattery")}
|
||||||
vertical={bind(config.vertical)}
|
vertical={bind(config.vertical)}
|
||||||
className={bind(className)}
|
className={bind(className)}
|
||||||
setup={self => setupCustomTooltip(self, bind(tooltip))}
|
setup={self => setupCustomTooltip(self, bind(tooltip))}
|
||||||
onDestroy={() => {
|
onDestroy={() => {
|
||||||
visible.drop();
|
|
||||||
className.drop();
|
className.drop();
|
||||||
tooltip.drop();
|
tooltip.drop();
|
||||||
}}
|
}}
|
||||||
|
|
@ -536,8 +538,8 @@ const Battery = ({ monitor, ...props }: ModuleProps) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DateTimeHoriz = (props: SpacerClassNameProps) => (
|
const DateTimeHoriz = (props: ClassNameProps) => (
|
||||||
<box className={`module date-time ${spacerClassName(props)}`}>
|
<box className={`module date-time ${getClassName(props)}`}>
|
||||||
<label className="icon" label="calendar_month" />
|
<label className="icon" label="calendar_month" />
|
||||||
<label
|
<label
|
||||||
setup={self => {
|
setup={self => {
|
||||||
|
|
@ -549,8 +551,8 @@ const DateTimeHoriz = (props: SpacerClassNameProps) => (
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const DateTimeVertical = (props: SpacerClassNameProps) => (
|
const DateTimeVertical = (props: ClassNameProps) => (
|
||||||
<box vertical className={`module date-time ${spacerClassName(props)}`}>
|
<box vertical className={`module date-time ${getClassName(props)}`}>
|
||||||
<label className="icon" label="calendar_month" />
|
<label className="icon" label="calendar_month" />
|
||||||
<label label={bindCurrentTime("%H")} />
|
<label label={bindCurrentTime("%H")} />
|
||||||
<label label={bindCurrentTime("%M")} />
|
<label label={bindCurrentTime("%M")} />
|
||||||
|
|
@ -559,7 +561,6 @@ const DateTimeVertical = (props: SpacerClassNameProps) => (
|
||||||
|
|
||||||
const DateTime = ({ monitor, ...props }: ModuleProps) => (
|
const DateTime = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.dateTime.enabled)}
|
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "time")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "time")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
|
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
|
||||||
|
|
@ -571,8 +572,7 @@ const DateTime = ({ monitor, ...props }: ModuleProps) => (
|
||||||
|
|
||||||
const Power = ({ monitor, ...props }: ModuleProps) => (
|
const Power = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.power.enabled)}
|
className={`module power ${getClassName(props)}`}
|
||||||
className={`module power ${spacerClassName(props)}`}
|
|
||||||
label="power_settings_new"
|
label="power_settings_new"
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && App.toggle_window("session")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && App.toggle_window("session")}
|
||||||
/>
|
/>
|
||||||
|
|
@ -604,32 +604,51 @@ const VolumeSpacer = () => (
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Bar = ({ monitor }: { monitor: Monitor }) => {
|
const Bar = ({ monitor, layout }: { monitor: Monitor; layout: string }) => {
|
||||||
const className = Variable.derive(
|
const className = Variable.derive(
|
||||||
[bind(config.vertical), bind(config.style)],
|
[bind(config.vertical), bind(config.style)],
|
||||||
(v, s) => `bar ${v ? "vertical" : " horizontal"} ${s}`
|
(v, s) => `bar ${v ? "vertical" : " horizontal"} ${s}`
|
||||||
);
|
);
|
||||||
|
const modules =
|
||||||
|
layout === "centerbox"
|
||||||
|
? Variable.derive(Object.values(config.layout.centerbox))
|
||||||
|
: bind(config.layout.flowbox).as(m => [m]);
|
||||||
|
|
||||||
|
const Layout = layout === "centerbox" ? Widget.CenterBox : Widget.Box;
|
||||||
return (
|
return (
|
||||||
<centerbox vertical={bind(config.vertical)} className={bind(className)} onDestroy={() => className.drop()}>
|
<Layout
|
||||||
<box vertical={bind(config.vertical)}>
|
vertical={bind(config.vertical)}
|
||||||
<OSIcon monitor={monitor} />
|
className={bind(className)}
|
||||||
<ActiveWindow monitor={monitor} />
|
onDestroy={() => {
|
||||||
<MediaPlaying monitor={monitor} beforeSpacer />
|
className.drop();
|
||||||
<BrightnessSpacer monitor={monitor} />
|
if (modules instanceof Variable) modules.drop();
|
||||||
</box>
|
}}
|
||||||
<Workspaces monitor={monitor} beforeSpacer afterSpacer />
|
>
|
||||||
<box vertical={bind(config.vertical)}>
|
{bind(modules).as(modules =>
|
||||||
<VolumeSpacer />
|
modules.map((m, i) => (
|
||||||
<Tray monitor={monitor} afterSpacer />
|
<box vertical={bind(config.vertical)}>
|
||||||
<StatusIcons monitor={monitor} />
|
{m.map((n, j) => {
|
||||||
<PkgUpdates monitor={monitor} />
|
let beforeSpacer = false;
|
||||||
<NotifCount monitor={monitor} />
|
if (j < m.length - 1) beforeSpacer = isSpacer(m[j + 1]);
|
||||||
<Battery monitor={monitor} />
|
else if (i < modules.length - 1) beforeSpacer = isSpacer(modules[i + 1][0]);
|
||||||
<DateTime monitor={monitor} />
|
let afterSpacer = false;
|
||||||
<Power monitor={monitor} />
|
if (j > 0) afterSpacer = isSpacer(m[j - 1]);
|
||||||
</box>
|
else if (i > 0) afterSpacer = isSpacer(modules[i - 1].at(-1));
|
||||||
</centerbox>
|
const M = getModule(n);
|
||||||
|
return (
|
||||||
|
<M
|
||||||
|
monitor={monitor}
|
||||||
|
beforeSpacer={beforeSpacer}
|
||||||
|
afterSpacer={afterSpacer}
|
||||||
|
first={i === 0 && j === 0}
|
||||||
|
last={i === modules.length - 1 && j === m.length - 1}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</box>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -657,7 +676,9 @@ export default ({ monitor }: { monitor: Monitor }) => (
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Bar monitor={monitor} />
|
{bind(config.layout.type).as(l => (
|
||||||
|
<Bar monitor={monitor} layout={l} />
|
||||||
|
))}
|
||||||
</overlay>
|
</overlay>
|
||||||
</window>
|
</window>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue