nosignal-shell/modules/launcher/services/Apps.qml
Bora Gülerman 40a2552830
launcher: add favorite apps (#946)
* launcher: add favorite apps

Favorite apps always appear above non-favorite apps
Accepts regex, same logic as #920
Added the same regex logic to hidden apps
Added util file may need to be relocated

* addressed requested changes

* fix: Renamed newly added util singleton

Also added a null check to favorite icon loader in AppItem.qml

* controlCenter/launcherPane: added favorite apps

added icons to the app list to indicate if they are favorited/hidden
marking as favorite/hidden is desabled if the other is selected

* favouriteApps: renamed from favorite to favourite

Also disabled favorite/hidden switch for entries added as regex

* appDb: added notify and emit to favoriteApps

* controlCentre/Launcher: Fixed bug with favourite switch not enabling itself when no hiddenApps exist

Added a comment to explain the enabled state of the switches
icon loader is now a single loader rather than two, hidden icon has
priority

* spelling mistakes

* fixed warning

* formatting fixes
2026-02-19 21:26:10 +11:00

78 lines
2.5 KiB
QML

pragma Singleton
import qs.config
import qs.utils
import Caelestia
import Quickshell
Searcher {
id: root
function launch(entry: DesktopEntry): void {
appDb.incrementFrequency(entry.id);
if (entry.runInTerminal)
Quickshell.execDetached({
command: ["app2unit", "--", ...Config.general.apps.terminal, `${Quickshell.shellDir}/assets/wrap_term_launch.sh`, ...entry.command],
workingDirectory: entry.workingDirectory
});
else
Quickshell.execDetached({
command: ["app2unit", "--", ...entry.command],
workingDirectory: entry.workingDirectory
});
}
function search(search: string): list<var> {
const prefix = Config.launcher.specialPrefix;
if (search.startsWith(`${prefix}i `)) {
keys = ["id", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}c `)) {
keys = ["categories", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}d `)) {
keys = ["comment", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}e `)) {
keys = ["execString", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}w `)) {
keys = ["startupClass", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}g `)) {
keys = ["genericName", "name"];
weights = [0.9, 0.1];
} else if (search.startsWith(`${prefix}k `)) {
keys = ["keywords", "name"];
weights = [0.9, 0.1];
} else {
keys = ["name"];
weights = [1];
if (!search.startsWith(`${prefix}t `))
return query(search).map(e => e.entry);
}
const results = query(search.slice(prefix.length + 2)).map(e => e.entry);
if (search.startsWith(`${prefix}t `))
return results.filter(a => a.runInTerminal);
return results;
}
function selector(item: var): string {
return keys.map(k => item[k]).join(" ");
}
list: appDb.apps
useFuzzy: Config.launcher.useFuzzy.apps
AppDb {
id: appDb
path: `${Paths.state}/apps.sqlite`
favouriteApps: Config.launcher.favouriteApps
entries: DesktopEntries.applications.values.filter(a => !Strings.testRegexList(Config.launcher.hiddenApps, a.id))
}
}