From ba4a879cc7c44187c429cea629e05b106ca75802 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:21:26 +1100 Subject: launcher: use scrollable --- src/modules/launcher.tsx | 123 ++++++++++++++++++++++++++++++++--------------- src/services/math.ts | 3 +- 2 files changed, 86 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/modules/launcher.tsx b/src/modules/launcher.tsx index b588e3a..115137d 100644 --- a/src/modules/launcher.tsx +++ b/src/modules/launcher.tsx @@ -47,6 +47,9 @@ const getEmptyTextFromMode = (mode: Mode) => { } }; +const limitLength = (arr: T[], cfg: { maxResults: number }) => + cfg.maxResults > 0 && arr.length > cfg.maxResults ? arr.slice(0, cfg.maxResults) : arr; + const close = (self: JSX.Element) => { const toplevel = self.get_toplevel(); if (toplevel instanceof Widget.Window) toplevel.hide(); @@ -114,7 +117,7 @@ const PinnedApp = (names: string[]) => { return widget; }; -const PinnedApps = () => {config.pins.map(PinnedApp)}; +const PinnedApps = () => {config.apps.pins.map(PinnedApp)}; const SearchEntry = ({ entry }: { entry: Widget.Entry }) => ( void; onSecondaryClick?: (self: Widget.Button) => void; + onMiddleClick?: (self: Widget.Button) => void; onDestroy?: () => void; }) => ( @@ -388,18 +398,43 @@ const WindowResult = ({ client, reload }: { client: Client; reload: () => void } }) ); + const classOrTitle = (prop: "Class" | "Title", header = true) => { + const lower = prop.toLowerCase() as "class" | "title"; + return ( + (header ? `${prop}: ` : "") + + (client[lower] || (client[`initial${prop}`] ? `${client[`initial${prop}`]} (initial)` : `No ${lower}`)) + ); + }; + const workspace = (header = false) => + (header ? "Workspace: " : "") + `${client.workspace.name} (${client.workspace.id})`; + const prop = (prop: keyof typeof client, header?: string) => + `${header ?? prop.slice(0, 1).toUpperCase() + prop.slice(1)}: ${client[prop]}`; + const result = ( { close(self); astalClient?.focus(); }} onSecondaryClick={() => menu.popup_at_pointer(null)} + onMiddleClick={() => { + astalClient?.kill(); + const id = hyprland.connect("client-removed", () => { + hyprland.disconnect(id); + reload(); + }); + }} onDestroy={() => menu.destroy()} /> ); @@ -409,24 +444,10 @@ const WindowResult = ({ client, reload }: { client: Client; reload: () => void } const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) => { const empty = Variable(true); - return ( - (t ? "empty" : "list"))} - > - - + const scrollable = ( + { const subcommands: Record = { apps: { @@ -470,11 +491,16 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) }; const subcommandList = Object.keys(subcommands); - const updateEmpty = () => empty.set(self.get_children().length === 0); + const afterUpdate = () => { + empty.set(self.get_children().length === 0); + + const children = limitLength(self.get_children(), config); + const height = children.reduce((a, b) => a + b.get_preferred_height()[1], 0); + scrollable.css = `min-height: ${height}px;`; + }; const appSearch = () => { - const apps = Apps.fuzzy_query(entry.text); - if (apps.length > config.maxResults) apps.length = config.maxResults; + const apps = limitLength(Apps.fuzzy_query(entry.text), config.apps); for (const app of apps) self.add(); }; @@ -485,23 +511,23 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) ); self.add(); } - for (const item of MathService.get_default().history) + for (const item of limitLength(MathService.get_default().history, config.math)) self.add(); }; const fileSearch = () => - execAsync(["fd", ...config.fdOpts, entry.text, HOME]) + execAsync(["fd", ...config.files.fdOpts, entry.text, HOME]) .then(out => { const paths = out.split("\n").filter(path => path); - if (paths.length > config.maxResults) paths.length = config.maxResults; self.foreach(ch => ch.destroy()); - for (const path of paths) self.add(); + for (const path of limitLength(paths, config.files)) + self.add(); }) .catch(e => { // Ignore execAsync error if (!(e instanceof Gio.IOErrorEnum || e instanceof GLib.SpawnError)) console.error(e); }) - .finally(updateEmpty); + .finally(afterUpdate); const listWindows = () => { const hyprland = AstalHyprland.get_default(); @@ -512,13 +538,13 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) if (entry.text) { const clients = fuzzysort.go(entry.text, unsortedClients, { all: true, - limit: config.maxResults, + limit: config.windows.maxResults, keys: ["title", "class", "initialTitle", "initialClass"], scoreFn: r => - r[0].score * config.windows.title + - r[1].score * config.windows.class + - r[2].score * config.windows.initialTitle + - r[3].score * config.windows.initialClass, + r[0].score * config.windows.weights.title + + r[1].score * config.windows.weights.class + + r[2].score * config.windows.weights.initialTitle + + r[3].score * config.windows.weights.initialClass, }); self.foreach(ch => ch.destroy()); for (const { obj } of clients) @@ -526,13 +552,13 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) } else { const clients = unsortedClients.sort((a, b) => a.focusHistoryID - b.focusHistoryID); self.foreach(ch => ch.destroy()); - for (const client of clients) + for (const client of limitLength(clients, config.windows)) self.add(); } } catch (e) { console.error(e); } finally { - updateEmpty(); + afterUpdate(); } }); }; @@ -572,10 +598,29 @@ const Results = ({ entry, mode }: { entry: Widget.Entry; mode: Variable }) else if (mode.get() === "files") fileSearch(); else if (mode.get() === "windows") listWindows(); - if (ignoreFileAsync) updateEmpty(); + if (ignoreFileAsync) afterUpdate(); }); }} /> + + ) as Widget.Scrollable; + + return ( + (t ? "empty" : "list"))} + > + + + {scrollable} ); }; diff --git a/src/services/math.ts b/src/services/math.ts index c66798c..14e90e0 100644 --- a/src/services/math.ts +++ b/src/services/math.ts @@ -1,5 +1,6 @@ import { GLib, GObject, property, readFile, register, writeFileAsync } from "astal"; import { derivative, evaluate, rationalize, simplify } from "mathjs/number"; +import { math as config } from "../../config"; export interface HistoryItem { equation: string; @@ -16,7 +17,7 @@ export default class Math extends GObject.Object { return this.instance; } - readonly #maxHistory = 20; + readonly #maxHistory = config.maxHistory; readonly #path = `${CACHE}/math-history.json`; readonly #history: HistoryItem[] = []; -- cgit v1.2.3-freya