summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-14 19:53:49 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-14 19:53:49 +1100
commitc2e03775dba9aedbb52c9bf1135a2290faaa21bf (patch)
tree7909f68f820b68407f8c49e74d1464653d385348
parentlauncher: better math error message (diff)
downloadcaelestia-shell-c2e03775dba9aedbb52c9bf1135a2290faaa21bf.tar.gz
caelestia-shell-c2e03775dba9aedbb52c9bf1135a2290faaa21bf.tar.bz2
caelestia-shell-c2e03775dba9aedbb52c9bf1135a2290faaa21bf.zip
better config + notifpopups max popups
Use a config file
-rw-r--r--config.ts21
-rw-r--r--modules/bar.tsx12
-rw-r--r--modules/launcher.tsx36
-rw-r--r--modules/notifpopups.tsx20
4 files changed, 44 insertions, 45 deletions
diff --git a/config.ts b/config.ts
new file mode 100644
index 0000000..ccfa08a
--- /dev/null
+++ b/config.ts
@@ -0,0 +1,21 @@
+export const bar = {
+ wsPerGroup: 10,
+ dateTimeFormat: "%d/%m/%y %R",
+};
+
+export const launcher = {
+ maxResults: 15,
+ fdOpts: ["-a", "-t", "f"],
+ pins: [
+ ["firefox", "waterfox", "google-chrome", "chromium", "brave-browser", "vivaldi-stable", "vivaldi-snapshot"],
+ ["foot", "alacritty", "kitty", "wezterm"],
+ ["thunar", "nemo", "nautilus"],
+ ["codium", "code", "clion", "intellij-idea-ultimate-edition"],
+ ["spotify-adblock", "spotify", "audacious", "elisa"],
+ ],
+};
+
+export const notifpopups = {
+ maxPopups: -1,
+ expire: false,
+};
diff --git a/modules/bar.tsx b/modules/bar.tsx
index bf1bb9f..ed888db 100644
--- a/modules/bar.tsx
+++ b/modules/bar.tsx
@@ -4,6 +4,7 @@ import { App, Astal, astalify, Gdk, Gtk, type ConstructProps } from "astal/gtk3"
import AstalHyprland from "gi://AstalHyprland";
import AstalNotifd from "gi://AstalNotifd";
import AstalTray from "gi://AstalTray";
+import { bar as config } from "../config";
import Players from "../services/players";
import { getAppCategoryIcon } from "../utils/icons";
import { ellipsize } from "../utils/strings";
@@ -12,8 +13,6 @@ import { setupCustomTooltip } from "../utils/widgets";
const hyprland = AstalHyprland.get_default();
-const wsPerGroup = 10;
-
const hookFocusedClientProp = (
self: any, // Ugh why is there no base Widget type
prop: keyof AstalHyprland.Client,
@@ -99,7 +98,7 @@ const MediaPlaying = () => {
};
const Workspace = ({ idx }: { idx: number }) => {
- let wsId = Math.floor((hyprland.focusedWorkspace.id - 1) / wsPerGroup) * wsPerGroup + idx;
+ let wsId = Math.floor((hyprland.focusedWorkspace.id - 1) / config.wsPerGroup) * config.wsPerGroup + idx;
return (
<button
halign={Gtk.Align.CENTER}
@@ -115,7 +114,7 @@ const Workspace = ({ idx }: { idx: number }) => {
};
self.hook(hyprland, "notify::focused-workspace", () => {
- wsId = Math.floor((hyprland.focusedWorkspace.id - 1) / wsPerGroup) * wsPerGroup + idx;
+ wsId = Math.floor((hyprland.focusedWorkspace.id - 1) / config.wsPerGroup) * config.wsPerGroup + idx;
update();
});
self.hook(hyprland, "client-added", update);
@@ -138,7 +137,7 @@ const Workspaces = () => (
}}
>
<box className="module workspaces">
- {Array.from({ length: wsPerGroup }).map((_, idx) => (
+ {Array.from({ length: config.wsPerGroup }).map((_, idx) => (
<Workspace idx={idx + 1} /> // Start from 1
))}
</box>
@@ -237,7 +236,8 @@ const DateTime = () => (
<label
setup={self => {
const pollVar = Variable(null).poll(5000, () => {
- self.label = GLib.DateTime.new_now_local().format("%d/%m/%y %R") ?? new Date().toLocaleString();
+ self.label =
+ GLib.DateTime.new_now_local().format(config.dateTimeFormat) ?? new Date().toLocaleString();
return null;
});
self.connect("destroy", () => pollVar.drop());
diff --git a/modules/launcher.tsx b/modules/launcher.tsx
index b9ab20b..20b7c0d 100644
--- a/modules/launcher.tsx
+++ b/modules/launcher.tsx
@@ -3,6 +3,7 @@ import { Astal, Gtk, Widget } from "astal/gtk3";
import fuzzysort from "fuzzysort";
import type AstalApps from "gi://AstalApps";
import AstalHyprland from "gi://AstalHyprland";
+import { launcher as config } from "../config";
import { Apps } from "../services/apps";
import Math, { type HistoryItem } from "../services/math";
import { HOME } from "../utils/constants";
@@ -19,23 +20,6 @@ interface Subcommand {
command: (...args: string[]) => void;
}
-const maxSearchResults = 15;
-const fdOptions = ["-a", "-t", "f", "-E", ".git"];
-
-const browser = [
- "firefox",
- "waterfox",
- "google-chrome",
- "chromium",
- "brave-browser",
- "vivaldi-stable",
- "vivaldi-snapshot",
-];
-const terminal = ["foot", "alacritty", "kitty", "wezterm"];
-const files = ["thunar", "nemo", "nautilus"];
-const ide = ["codium", "code", "clion", "intellij-idea-ultimate-edition"];
-const music = ["spotify-adblock", "spotify", "audacious", "elisa"];
-
const getIconFromMode = (mode: Mode) => {
switch (mode) {
case "apps":
@@ -77,7 +61,7 @@ const openFileAndClose = (self: JSX.Element, path: string) => {
]).catch(console.error);
};
-const PinnedApp = ({ names }: { names: string[] }) => {
+const PinnedApp = (names: string[]) => {
let app: Gio.DesktopAppInfo | null = null;
let astalApp: AstalApps.Application | undefined;
for (const name of names) {
@@ -103,15 +87,7 @@ const PinnedApp = ({ names }: { names: string[] }) => {
) : null;
};
-const PinnedApps = () => (
- <box homogeneous>
- <PinnedApp names={browser} />
- <PinnedApp names={terminal} />
- <PinnedApp names={files} />
- <PinnedApp names={ide} />
- <PinnedApp names={music} />
- </box>
-);
+const PinnedApps = () => <box homogeneous>{config.pins.map(PinnedApp)}</box>;
const SearchEntry = ({ entry }: { entry: Widget.Entry }) => (
<stack
@@ -275,7 +251,7 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable<Mode> })
const appSearch = () => {
const apps = Apps.fuzzy_query(entry.text);
- if (apps.length > maxSearchResults) apps.length = maxSearchResults;
+ if (apps.length > config.maxResults) apps.length = config.maxResults;
for (const app of apps) self.add(<AppResult app={app} />);
};
@@ -289,10 +265,10 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable<Mode> })
};
const fileSearch = () =>
- execAsync(["fd", ...fdOptions, entry.text, HOME])
+ execAsync(["fd", ...config.fdOpts, entry.text, HOME])
.then(out => {
const paths = out.split("\n").filter(path => path);
- if (paths.length > maxSearchResults) paths.length = maxSearchResults;
+ if (paths.length > config.maxResults) paths.length = config.maxResults;
self.foreach(ch => ch.destroy());
for (const path of paths) self.add(<FileResult path={path} />);
})
diff --git a/modules/notifpopups.tsx b/modules/notifpopups.tsx
index a46f218..1830079 100644
--- a/modules/notifpopups.tsx
+++ b/modules/notifpopups.tsx
@@ -1,6 +1,7 @@
import { GLib, register, timeout } from "astal";
import { Astal, Gtk, Widget } from "astal/gtk3";
import AstalNotifd from "gi://AstalNotifd";
+import { notifpopups as config } from "../config";
import { desktopEntrySubs } from "../utils/icons";
import { setupChildClickthrough } from "../utils/widgets";
@@ -104,8 +105,8 @@ class NotifPopup extends Widget.Box {
this.css = `transition: 300ms cubic-bezier(0.05, 0.9, 0.1, 1.1); margin-left: 0; margin-right: 0;`;
});
- // Close popup after timeout if transient
- if (notification.transient)
+ // Close popup after timeout if transient or expire enabled in config
+ if (config.expire || notification.transient)
timeout(
notification.expireTimeout > 0
? notification.expireTimeout
@@ -145,8 +146,11 @@ export default () => (
const map = new Map<number, NotifPopup>();
self.hook(notifd, "notified", (self, id) => {
const notification = notifd.get_notification(id);
+
const popup = (<NotifPopup notification={notification} />) as NotifPopup;
+ popup.connect("destroy", () => map.delete(notification.id));
map.set(notification.id, popup);
+
self.add(
<eventbox
// Dismiss on middle click
@@ -157,14 +161,12 @@ export default () => (
{popup}
</eventbox>
);
+
+ // Limit number of popups
+ if (config.maxPopups > 0 && self.children.length > config.maxPopups)
+ map.values().next().value?.destroyWithAnims();
});
- self.hook(notifd, "resolved", (_, id) => {
- const popup = map.get(id);
- if (popup) {
- popup.destroyWithAnims();
- map.delete(id);
- }
- });
+ self.hook(notifd, "resolved", (_, id) => map.get(id)?.destroyWithAnims());
// Change input region to child region so can click through empty space
setupChildClickthrough(self);