73 lines
2.7 KiB
TypeScript
73 lines
2.7 KiB
TypeScript
import Apps from "gi://AstalApps";
|
|
import AstalHyprland from "gi://AstalHyprland";
|
|
|
|
const app_icons = new Apps.Apps().list.reduce(
|
|
(acc, app) => {
|
|
// keys from AstalApps entries are typically wm_class (snake_case) or name
|
|
const key = app.wm_class ?? app.name;
|
|
if (key) {
|
|
acc.classOrNames[key] = app.icon_name;
|
|
}
|
|
if (app.executable) {
|
|
acc.executables[app.executable] = app.icon_name;
|
|
}
|
|
return acc;
|
|
},
|
|
{ classOrNames: {} as Record<string, string>, executables: {} as Record<string, string> },
|
|
);
|
|
|
|
export function getIconName(client: AstalHyprland.Client | null | undefined) {
|
|
if (!client) return "";
|
|
|
|
// try a bunch of fields (snake_case and camelCase variants)
|
|
const possibleKeys = [
|
|
// common client properties (snake_case)
|
|
(client as any).wm_class,
|
|
(client as any).initial_class,
|
|
(client as any).executable,
|
|
// camelCase variants (some bindings expose these)
|
|
(client as any).class,
|
|
(client as any).initialClass,
|
|
(client as any).initialTitle,
|
|
(client as any).title,
|
|
(client as any).name,
|
|
].filter(Boolean) as string[];
|
|
|
|
// 1) direct exact match
|
|
for (const k of possibleKeys) {
|
|
const icon = app_icons.classOrNames[k] ?? app_icons.executables[k];
|
|
if (icon) {
|
|
// cache the mapping for this client's canonical class (prefer wm_class or class)
|
|
const cacheKey = (client as any).wm_class ?? (client as any).class ?? (client as any).name ?? k;
|
|
app_icons.classOrNames[cacheKey] = icon;
|
|
return icon;
|
|
}
|
|
}
|
|
|
|
// 2) fuzzy match: see if any stored key includes any of the client strings (title, name, etc.)
|
|
const searchStrings = [
|
|
(client as any).title,
|
|
(client as any).initialTitle,
|
|
(client as any).initial_class,
|
|
(client as any).initialClass,
|
|
(client as any).wm_class,
|
|
(client as any).class,
|
|
(client as any).name,
|
|
].filter(Boolean) as string[];
|
|
|
|
for (const s of searchStrings) {
|
|
const matchKey = Object.keys(app_icons.classOrNames).find((key) => key.includes(s));
|
|
if (matchKey) {
|
|
const icon = app_icons.classOrNames[matchKey];
|
|
const cacheKey = (client as any).wm_class ?? (client as any).class ?? (client as any).name ?? s;
|
|
app_icons.classOrNames[cacheKey] = icon;
|
|
return icon;
|
|
}
|
|
}
|
|
|
|
// nothing found — cache empty string so we don't repeat work
|
|
const cacheKey = (client as any).wm_class ?? (client as any).class ?? (client as any).name ?? "";
|
|
if (cacheKey) app_icons.classOrNames[cacheKey] = "";
|
|
return "";
|
|
}
|