31
flake.lock
generated
31
flake.lock
generated
@@ -5,23 +5,23 @@
|
|||||||
"astal": [
|
"astal": [
|
||||||
"astal"
|
"astal"
|
||||||
],
|
],
|
||||||
|
"gnim": "gnim",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1744557573,
|
"lastModified": 1751192975,
|
||||||
"narHash": "sha256-XAyj0iDuI51BytJ1PwN53uLpzTDdznPDQFG4RwihlTQ=",
|
"narHash": "sha256-X2WQxQZX9aktyaFQW94a4eCO0BYkLm9FZr9dyjVS7Sg=",
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"repo": "ags",
|
"repo": "ags",
|
||||||
"rev": "3ed9737bdbc8fc7a7c7ceef2165c9109f336bff6",
|
"rev": "74cdd7eabf0884a7d5ba0b300849891a7e89697e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"repo": "ags",
|
"repo": "ags",
|
||||||
"rev": "3ed9737bdbc8fc7a7c7ceef2165c9109f336bff6",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -32,18 +32,17 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749559749,
|
"lastModified": 1751126708,
|
||||||
"narHash": "sha256-TM95tg1G7S6rVBBoMwurXMz8Il4xlnuZ2TI4h6lfZzg=",
|
"narHash": "sha256-AodIKw7TmI7rHVcOfEsO82stupMYIMVQeLAUQfVxnkU=",
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"repo": "astal",
|
"repo": "astal",
|
||||||
"rev": "dd8a4662f2f17fb4326a7bd0fb2d054f5d477ba3",
|
"rev": "ac90f09385a2295da9fdc108aaba4a317aaeacc7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"repo": "astal",
|
"repo": "astal",
|
||||||
"rev": "dd8a4662f2f17fb4326a7bd0fb2d054f5d477ba3",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -110,6 +109,22 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gnim": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1751120710,
|
||||||
|
"narHash": "sha256-sT1ILM8m1QG8CeMmqLHhW/8T/MzUq3JL9jO3V7FMa4w=",
|
||||||
|
"owner": "aylur",
|
||||||
|
"repo": "gnim",
|
||||||
|
"rev": "5d2b734be452e2819f3a7313dbb34fa43c23e5d9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "aylur",
|
||||||
|
"repo": "gnim",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@@ -99,9 +99,6 @@
|
|||||||
repo = "astal";
|
repo = "astal";
|
||||||
ref = "main";
|
ref = "main";
|
||||||
|
|
||||||
# TODO: Update
|
|
||||||
rev = "dd8a4662f2f17fb4326a7bd0fb2d054f5d477ba3";
|
|
||||||
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,9 +108,6 @@
|
|||||||
repo = "ags";
|
repo = "ags";
|
||||||
ref = "main";
|
ref = "main";
|
||||||
|
|
||||||
# TODO: Update
|
|
||||||
rev = "3ed9737bdbc8fc7a7c7ceef2165c9109f336bff6";
|
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.follows = "nixpkgs";
|
nixpkgs.follows = "nixpkgs";
|
||||||
astal.follows = "astal";
|
astal.follows = "astal";
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { App } from "astal/gtk3";
|
import app from "ags/gtk3/app";
|
||||||
import { monitorFile } from "astal/file";
|
import { exec } from "ags/process";
|
||||||
import { exec } from "astal/process";
|
import { monitorFile } from "ags/file";
|
||||||
import GLib from "gi://GLib";
|
import GLib from "gi://GLib";
|
||||||
import Left from "./widget/Left";
|
import Left from "./widget/Left";
|
||||||
import Center from "./widget/Center";
|
import Center from "./widget/Center";
|
||||||
@@ -12,15 +12,15 @@ const scss = `${HOME}/.config/astal/theme.sass`;
|
|||||||
|
|
||||||
monitorFile(scss, () => {
|
monitorFile(scss, () => {
|
||||||
exec(`sassc ${scss} ${css}`);
|
exec(`sassc ${scss} ${css}`);
|
||||||
App.apply_css(css, true);
|
app.apply_css(css, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
exec(`sassc ${scss} ${css}`);
|
exec(`sassc ${scss} ${css}`);
|
||||||
|
|
||||||
App.start({
|
app.start({
|
||||||
css,
|
css,
|
||||||
main() {
|
main() {
|
||||||
App.get_monitors().map((monitor) => {
|
app.get_monitors().map((monitor) => {
|
||||||
Left(monitor);
|
Left(monitor);
|
||||||
Center(monitor);
|
Center(monitor);
|
||||||
Right(monitor);
|
Right(monitor);
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { Gdk } from "astal/gtk3";
|
import { Gdk } from "ags/gtk3";
|
||||||
import Hyprland from "gi://AstalHyprland";
|
import Hyprland from "gi://AstalHyprland";
|
||||||
|
|
||||||
export const range = (length: number, start = 1) => {
|
export const range = (length: number, start = 1) => {
|
||||||
return Array.from({ length }, (n, i) => i + start);
|
return Array.from({ length }, (_, i) => i + start);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getHyprlandMonitor = (gdkmonitor: Gdk.Monitor) => {
|
export const getHyprlandMonitor = (gdkmonitor: Gdk.Monitor) => {
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "astal-shell",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"astal": "~/.local/share/ags"
|
"ags": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"experimentalDecorators": true,
|
"jsx": "react-jsx",
|
||||||
"strict": true,
|
"jsxImportSource": "ags/gtk3",
|
||||||
"target": "ES2022",
|
"lib": ["ES2023"],
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"jsx": "react-jsx",
|
"strict": true,
|
||||||
"jsxImportSource": "astal/gtk3"
|
"target": "ES2020"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,19 @@
|
|||||||
import { App, Astal, Gtk, Gdk } from "astal/gtk3";
|
import { Astal, Gtk, Gdk } from "ags/gtk3";
|
||||||
import Date from "./components/Date";
|
import Date from "./components/Date";
|
||||||
import Hidden from "./components/Hidden";
|
import Hidden from "./components/Hidden";
|
||||||
|
import app from "ags/gtk3/app";
|
||||||
|
|
||||||
export default (monitor: Gdk.Monitor) => (
|
export default (monitor: Gdk.Monitor) => (
|
||||||
<window
|
<window
|
||||||
className="root"
|
visible
|
||||||
|
class="root"
|
||||||
gdkmonitor={monitor}
|
gdkmonitor={monitor}
|
||||||
exclusivity={Astal.Exclusivity.IGNORE}
|
exclusivity={Astal.Exclusivity.IGNORE}
|
||||||
anchor={Astal.WindowAnchor.TOP}
|
anchor={Astal.WindowAnchor.TOP}
|
||||||
application={App}
|
application={app}
|
||||||
>
|
>
|
||||||
<Hidden>
|
<Hidden>
|
||||||
<box className="widgets" hexpand halign={Gtk.Align.CENTER}>
|
<box class="widgets" hexpand halign={Gtk.Align.CENTER}>
|
||||||
<Date />
|
<Date />
|
||||||
</box>
|
</box>
|
||||||
</Hidden>
|
</Hidden>
|
||||||
|
@@ -1,21 +1,22 @@
|
|||||||
import { App, Astal, Gtk, Gdk } from "astal/gtk3";
|
import { Astal, Gtk, Gdk } from "ags/gtk3";
|
||||||
|
import app from "ags/gtk3/app";
|
||||||
import Launcher from "./components/Launcher";
|
import Launcher from "./components/Launcher";
|
||||||
import Workspace from "./components/Workspaces";
|
import Workspace from "./components/Workspaces";
|
||||||
import Hidden from "./components/Hidden";
|
import Hidden from "./components/Hidden";
|
||||||
import { getHyprlandMonitor } from "../lib";
|
|
||||||
|
|
||||||
export default (monitor: Gdk.Monitor) => (
|
export default (monitor: Gdk.Monitor) => (
|
||||||
<window
|
<window
|
||||||
className="root"
|
visible
|
||||||
|
class="root"
|
||||||
gdkmonitor={monitor}
|
gdkmonitor={monitor}
|
||||||
exclusivity={Astal.Exclusivity.IGNORE}
|
exclusivity={Astal.Exclusivity.IGNORE}
|
||||||
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT}
|
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT}
|
||||||
application={App}
|
application={app}
|
||||||
>
|
>
|
||||||
<Hidden>
|
<Hidden>
|
||||||
<box className="widgets" hexpand halign={Gtk.Align.START}>
|
<box class="widgets" hexpand halign={Gtk.Align.START}>
|
||||||
<Launcher />
|
<Launcher />
|
||||||
<Workspace monitor={getHyprlandMonitor(monitor)!} />
|
<Workspace gdkmonitor={monitor} />
|
||||||
</box>
|
</box>
|
||||||
</Hidden>
|
</Hidden>
|
||||||
</window>
|
</window>
|
||||||
|
@@ -1,18 +1,21 @@
|
|||||||
import { App, Astal, Gtk, Gdk } from "astal/gtk3";
|
import { Astal, Gtk } from "ags/gtk3";
|
||||||
|
import app from "ags/gtk3/app";
|
||||||
|
import Gdk from "gi://Gdk";
|
||||||
import Systray from "./components/Tray";
|
import Systray from "./components/Tray";
|
||||||
import Hidden from "./components/Hidden";
|
import Hidden from "./components/Hidden";
|
||||||
import Battery from "./components/Battery";
|
import Battery from "./components/Battery";
|
||||||
|
|
||||||
export default (monitor: Gdk.Monitor) => (
|
export default (monitor: Gdk.Monitor) => (
|
||||||
<window
|
<window
|
||||||
className="root"
|
visible
|
||||||
|
class="root"
|
||||||
gdkmonitor={monitor}
|
gdkmonitor={monitor}
|
||||||
exclusivity={Astal.Exclusivity.IGNORE}
|
exclusivity={Astal.Exclusivity.IGNORE}
|
||||||
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT}
|
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT}
|
||||||
application={App}
|
application={app}
|
||||||
>
|
>
|
||||||
<Hidden>
|
<Hidden>
|
||||||
<box className="widgets" hexpand halign={Gtk.Align.END}>
|
<box class="widgets" hexpand halign={Gtk.Align.END}>
|
||||||
<Systray />
|
<Systray />
|
||||||
<Battery />
|
<Battery />
|
||||||
</box>
|
</box>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { bind, Variable } from "astal";
|
import { createBinding, createComputed } from "ags";
|
||||||
import AstalBattery from "gi://AstalBattery";
|
import AstalBattery from "gi://AstalBattery";
|
||||||
|
|
||||||
const battery = AstalBattery.get_default();
|
const battery = AstalBattery.get_default();
|
||||||
@@ -9,19 +9,19 @@ const formatTime = (seconds: number) =>
|
|||||||
: "--:--";
|
: "--:--";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const percentage = bind(battery, "percentage").as(
|
const percentage = createBinding(battery, "percentage").as(
|
||||||
(p) => Math.round(p * 100) + "%",
|
(p) => Math.round(p * 100) + "%",
|
||||||
);
|
);
|
||||||
const charging = bind(battery, "charging");
|
const charging = createBinding(battery, "charging");
|
||||||
const timeToFull = bind(battery, "timeToFull");
|
const timeToFull = createBinding(battery, "timeToFull");
|
||||||
const timeToEmpty = bind(battery, "timeToEmpty");
|
const timeToEmpty = createBinding(battery, "timeToEmpty");
|
||||||
|
|
||||||
const time = Variable.derive(
|
const time = createComputed(
|
||||||
[charging, timeToFull, timeToEmpty],
|
[charging, timeToFull, timeToEmpty],
|
||||||
(charging, full, empty) => formatTime(charging ? full : empty),
|
(charging, full, empty) => formatTime(charging ? full : empty),
|
||||||
);
|
);
|
||||||
|
|
||||||
const label = Variable.derive(
|
const label = createComputed(
|
||||||
[percentage, charging, time],
|
[percentage, charging, time],
|
||||||
(percentage, charging, time) => {
|
(percentage, charging, time) => {
|
||||||
const arrow = charging ? "▲" : "▼";
|
const arrow = charging ? "▲" : "▼";
|
||||||
@@ -30,8 +30,8 @@ export default () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className="battery">
|
<button class="battery">
|
||||||
<label className="label" label={bind(label)} />
|
<label class="label" label={label} />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,21 +1,16 @@
|
|||||||
import { bind, Variable } from "astal";
|
import { createPoll } from "ags/time";
|
||||||
import { GLib } from "astal";
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const time = Variable(
|
const time = createPoll(
|
||||||
GLib.DateTime.new_now_local().format("%H:%M - %A, %d %B %Y")!,
|
GLib.DateTime.new_now_local().format("%H:%M - %A, %d %B %Y")!,
|
||||||
).poll(
|
|
||||||
1000,
|
1000,
|
||||||
() => GLib.DateTime.new_now_local().format("%H:%M - %A, %d %B %Y")!,
|
() => GLib.DateTime.new_now_local().format("%H:%M - %A, %d %B %Y")!,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className="date">
|
<button class="date">
|
||||||
<label
|
<label class="label" label={time} />
|
||||||
className="label"
|
|
||||||
onDestroy={() => time.drop()}
|
|
||||||
label={bind(time)}
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { Gtk } from "astal/gtk3";
|
import { createState } from "ags";
|
||||||
import { Variable, bind, timeout } from "astal";
|
import { Gtk } from "ags/gtk3";
|
||||||
|
import { timeout } from "ags/time";
|
||||||
|
|
||||||
export default function Hidden({
|
export default function Hidden({
|
||||||
child,
|
child,
|
||||||
@@ -12,24 +13,20 @@ export default function Hidden({
|
|||||||
orientation?: Gtk.Orientation;
|
orientation?: Gtk.Orientation;
|
||||||
transitionType?: Gtk.RevealerTransitionType;
|
transitionType?: Gtk.RevealerTransitionType;
|
||||||
}) {
|
}) {
|
||||||
const show = Variable(true);
|
const [show, setShow] = createState(true);
|
||||||
const contents = child ?? children;
|
const contents = child ?? children;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<eventbox
|
<eventbox onHover={() => setShow(true)} onHoverLost={() => setShow(false)}>
|
||||||
clickThrough
|
|
||||||
onHover={() => show.set(true)}
|
|
||||||
onHoverLost={() => show.set(false)}
|
|
||||||
>
|
|
||||||
<box orientation={orientation}>
|
<box orientation={orientation}>
|
||||||
<revealer
|
<revealer
|
||||||
setup={(self) => timeout(2000, () => (self.revealChild = false))}
|
onRealize={() => timeout(2000, () => setShow(false))}
|
||||||
revealChild={bind(show)}
|
revealChild={show}
|
||||||
transitionType={transitionType}
|
transitionType={transitionType}
|
||||||
>
|
>
|
||||||
{Array.isArray(contents) ? <>{contents}</> : contents}
|
{Array.isArray(contents) ? <>{contents}</> : contents}
|
||||||
</revealer>
|
</revealer>
|
||||||
<box clickThrough className="trigger-guard" />
|
<box class="trigger-guard" />
|
||||||
</box>
|
</box>
|
||||||
</eventbox>
|
</eventbox>
|
||||||
);
|
);
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
import { execAsync } from "astal/process";
|
import { execAsync } from "ags/process";
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<button
|
<button
|
||||||
className="launcher"
|
class="launcher"
|
||||||
onClickRelease={() =>
|
onClicked={() =>
|
||||||
execAsync(
|
execAsync(
|
||||||
'rofi -modes drun -show drun -run-command \"uwsm app -- {cmd}\"',
|
'rofi -modes drun -show drun -run-command \"uwsm app -- {cmd}\"',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<icon className="icon" icon="nix-snowflake-symbolic" />;
|
<icon class="icon" icon="nix-snowflake-symbolic" />;
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
@@ -1,28 +1,31 @@
|
|||||||
import { App } from "astal/gtk3";
|
import { createBinding, For } from "ags";
|
||||||
import { bind } from "astal";
|
import app from "ags/gtk3/app";
|
||||||
import Tray from "gi://AstalTray";
|
import Tray from "gi://AstalTray";
|
||||||
|
|
||||||
const tray = Tray.get_default();
|
const tray = Tray.get_default();
|
||||||
|
|
||||||
const TrayButton = ({ item }: { item: Tray.TrayItem }) => (
|
const TrayButton = ({ item }: { item: Tray.TrayItem }) => (
|
||||||
<menubutton
|
<menubutton
|
||||||
className="item"
|
class="item"
|
||||||
tooltipMarkup={bind(item, "tooltipMarkup")}
|
tooltipMarkup={createBinding(item, "tooltipMarkup")}
|
||||||
usePopover={false}
|
usePopover={false}
|
||||||
menuModel={bind(item, "menuModel")}
|
menuModel={createBinding(item, "menuModel")}
|
||||||
actionGroup={bind(item, "actionGroup").as((ag) => ["dbusmenu", ag])}
|
|
||||||
>
|
>
|
||||||
<icon gicon={bind(item, "gicon")} />
|
<icon gicon={createBinding(item, "gicon")} />
|
||||||
</menubutton>
|
</menubutton>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default () => (
|
export default () => {
|
||||||
<box className="systray">
|
let items = createBinding(tray, "items");
|
||||||
{bind(tray, "items").as((items) =>
|
|
||||||
items.map((item) => {
|
return (
|
||||||
if (item.iconThemePath) App.add_icons(item.iconThemePath);
|
<box class="systray">
|
||||||
return <TrayButton item={item} />;
|
<For each={items}>
|
||||||
}),
|
{(item, _) => {
|
||||||
)}
|
if (item.iconThemePath) app.add_icons(item.iconThemePath);
|
||||||
</box>
|
return <TrayButton item={item} />;
|
||||||
);
|
}}
|
||||||
|
</For>
|
||||||
|
</box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@@ -1,74 +1,83 @@
|
|||||||
import { bind, Variable } from "astal";
|
|
||||||
import Hyprland from "gi://AstalHyprland";
|
import Hyprland from "gi://AstalHyprland";
|
||||||
import { range } from "../../lib";
|
import { getHyprlandMonitor, range } from "../../lib";
|
||||||
|
import {
|
||||||
|
Accessor,
|
||||||
|
createBinding,
|
||||||
|
createComputed,
|
||||||
|
createState,
|
||||||
|
Setter,
|
||||||
|
} from "ags";
|
||||||
|
import { Gdk, Gtk } from "ags/gtk3";
|
||||||
|
|
||||||
const hyprland = Hyprland.get_default();
|
const hyprland = Hyprland.get_default();
|
||||||
const BLOCK_SIZE = 10;
|
const BLOCK_SIZE = 10;
|
||||||
|
|
||||||
const Workspace = ({ id }: { id: number }) => {
|
const Workspace = ({ id }: { id: number }) => {
|
||||||
let clients: Variable<string[]>;
|
let clients: Accessor<string[]>;
|
||||||
|
let setClients: Setter<string[]>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const workspace = hyprland.get_workspace(id);
|
const workspace = hyprland.get_workspace(id);
|
||||||
clients = Variable(workspace.clients.map((client) => client.address));
|
[clients, setClients] = createState(
|
||||||
|
workspace.clients.map((client) => client.address),
|
||||||
|
);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
clients = Variable([]);
|
[clients, setClients] = createState<string[]>([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const active = Variable.derive(
|
const active = createComputed(
|
||||||
[bind(hyprland, "focusedWorkspace")],
|
[createBinding(hyprland, "focusedWorkspace")],
|
||||||
(focused) => focused.id == id,
|
(focused) => focused.id == id,
|
||||||
);
|
);
|
||||||
|
|
||||||
hyprland.connect("workspace-added", (_, workspace) => {
|
hyprland.connect("workspace-added", (_, workspace) => {
|
||||||
if (workspace.id != id) return;
|
if (workspace.id != id) return;
|
||||||
clients.set(workspace.clients.map((client) => client.address));
|
setClients(workspace.clients.map((client) => client.address));
|
||||||
});
|
});
|
||||||
|
|
||||||
hyprland.connect("workspace-removed", (_, workspaceId) => {
|
hyprland.connect("workspace-removed", (_, workspaceId) => {
|
||||||
if (workspaceId != id) return;
|
if (workspaceId != id) return;
|
||||||
clients.set([]);
|
setClients([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
hyprland.connect("client-added", (_hyprland, client) => {
|
hyprland.connect("client-added", (_hyprland, client) => {
|
||||||
if (client.workspace.id != id) return;
|
if (client.workspace.id != id) return;
|
||||||
clients.set([...clients.get(), client.address]);
|
setClients([...clients.get(), client.address]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Explicit separate event handling instead of Variable.derive(workspaces, clients)
|
|
||||||
// because client-moved events appear to be broken if done that way.
|
|
||||||
hyprland.connect("client-moved", (_hyprland, client, workspace) => {
|
hyprland.connect("client-moved", (_hyprland, client, workspace) => {
|
||||||
if (workspace.id == id) {
|
if (workspace.id == id) {
|
||||||
clients.set([...clients.get(), client.address]);
|
setClients([...clients.get(), client.address]);
|
||||||
} else {
|
} else {
|
||||||
clients.set(
|
setClients(
|
||||||
clients.get().filter((oldClient) => oldClient != client.address),
|
clients.get().filter((oldClient) => oldClient != client.address),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
hyprland.connect("client-removed", (_hyprland, address) => {
|
hyprland.connect("client-removed", (_hyprland, address) => {
|
||||||
clients.set(clients.get().filter((oldClient) => oldClient != address));
|
setClients(clients.get().filter((oldClient) => oldClient != address));
|
||||||
});
|
});
|
||||||
|
|
||||||
const className = Variable.derive([active, clients], (active, clients) => {
|
const className = createComputed([active, clients], (active, clients) => {
|
||||||
if (active) return "button active";
|
if (active) return "button active";
|
||||||
if (clients.length > 0) return "button occupied";
|
if (clients.length > 0) return "button occupied";
|
||||||
return "button";
|
return "button";
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<box vertical>
|
<box orientation={Gtk.Orientation.VERTICAL}>
|
||||||
<box vexpand />
|
<box vexpand />
|
||||||
<eventbox onClickRelease={() => hyprland.dispatch("workspace", `${id}`)}>
|
<eventbox onClickRelease={() => hyprland.dispatch("workspace", `${id}`)}>
|
||||||
<label className={className()} />
|
<label class={className} />
|
||||||
</eventbox>
|
</eventbox>
|
||||||
<box vexpand />
|
<box vexpand />
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ({ monitor }: { monitor: Hyprland.Monitor }) => {
|
export default ({ gdkmonitor }: { gdkmonitor: Gdk.Monitor }) => {
|
||||||
|
const monitor = getHyprlandMonitor(gdkmonitor)!;
|
||||||
const workspaces = hyprland.get_workspaces();
|
const workspaces = hyprland.get_workspaces();
|
||||||
const displayWorkspaces = workspaces.filter(
|
const displayWorkspaces = workspaces.filter(
|
||||||
(w) => w.monitor.id === monitor.id,
|
(w) => w.monitor.id === monitor.id,
|
||||||
@@ -78,7 +87,7 @@ export default ({ monitor }: { monitor: Hyprland.Monitor }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<eventbox
|
<eventbox
|
||||||
className="workspaces"
|
class="workspaces"
|
||||||
onScroll={(_, e) => {
|
onScroll={(_, e) => {
|
||||||
hyprland.dispatch("workspace", e.delta_y > 0 ? "m+1" : "m-1");
|
hyprland.dispatch("workspace", e.delta_y > 0 ? "m+1" : "m-1");
|
||||||
}}
|
}}
|
||||||
|
Reference in New Issue
Block a user