1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-26 14:32:52 -05:00

launcher: add name, icon, description overrides + hide/unhide options

- convenient helpers without needing to make .desktop overrides
fixes #1329
This commit is contained in:
bbedward
2026-01-18 20:30:50 -05:00
parent 7cb39f00ad
commit 0f6ae11c3d
14 changed files with 1359 additions and 397 deletions

View File

@@ -10,6 +10,8 @@ Singleton {
property var applications: []
property var _cachedCategories: null
property var _cachedVisibleApps: null
property var _hiddenAppsSet: new Set()
readonly property int maxResults: 10
readonly property int frecencySampleSize: 10
@@ -40,6 +42,51 @@ Singleton {
function refreshApplications() {
applications = DesktopEntries.applications.values;
_cachedCategories = null;
_cachedVisibleApps = null;
}
function _rebuildHiddenSet() {
_hiddenAppsSet = new Set(SessionData.hiddenApps || []);
_cachedVisibleApps = null;
}
function isAppHidden(app) {
if (!app)
return false;
const appId = app.id || app.execString || app.exec || "";
return _hiddenAppsSet.has(appId);
}
function getVisibleApplications() {
if (_cachedVisibleApps === null) {
_cachedVisibleApps = applications.filter(app => !isAppHidden(app));
}
return _cachedVisibleApps.map(app => applyAppOverride(app));
}
Connections {
target: SessionData
function onHiddenAppsChanged() {
root._rebuildHiddenSet();
}
function onAppOverridesChanged() {
root._cachedVisibleApps = null;
}
}
function applyAppOverride(app) {
if (!app)
return app;
const appId = app.id || app.execString || app.exec || "";
const override = SessionData.getAppOverride(appId);
if (!override)
return app;
return Object.assign({}, app, {
name: override.name || app.name,
icon: override.icon || app.icon,
comment: override.comment || app.comment,
_override: override
});
}
readonly property string dmsLogoPath: Qt.resolvedUrl("../assets/danklogo2.svg")
@@ -226,7 +273,10 @@ Singleton {
}
}
Component.onCompleted: refreshApplications()
Component.onCompleted: {
_rebuildHiddenSet();
refreshApplications();
}
function tokenize(text) {
return text.toLowerCase().trim().split(/[\s\-_]+/).filter(w => w.length > 0);
@@ -345,17 +395,17 @@ Singleton {
}
function searchApplications(query) {
if (!query || query.length === 0) {
return applications;
}
if (!query || query.length === 0)
return getVisibleApplications();
if (applications.length === 0)
return [];
const queryLower = query.toLowerCase().trim();
const scoredApps = [];
const results = [];
const visibleApps = getVisibleApplications();
for (const app of applications) {
for (const app of visibleApps) {
const name = (app.name || "").toLowerCase();
const genericName = (app.genericName || "").toLowerCase();
const comment = (app.comment || "").toLowerCase();
@@ -440,10 +490,58 @@ Singleton {
});
}
if (SessionData.searchAppActions) {
const actionResults = searchAppActions(queryLower, visibleApps);
for (const actionResult of actionResults) {
scoredApps.push({
app: actionResult.app,
score: actionResult.score
});
}
}
scoredApps.sort((a, b) => b.score - a.score);
return scoredApps.slice(0, maxResults).map(item => item.app);
}
function searchAppActions(query, apps) {
const results = [];
for (const app of apps) {
if (!app.actions || app.actions.length === 0)
continue;
for (const action of app.actions) {
const actionName = (action.name || "").toLowerCase();
if (!actionName)
continue;
let score = 0;
if (actionName === query) {
score = 8000;
} else if (actionName.startsWith(query)) {
score = 4000;
} else if (actionName.includes(query)) {
score = 400;
}
if (score > 0) {
results.push({
app: {
name: action.name,
icon: action.icon || app.icon,
comment: app.name,
categories: app.categories || [],
isAction: true,
parentApp: app,
actionData: action
},
score: score
});
}
}
}
return results;
}
function getCategoriesForApp(app) {
if (!app?.categories)
return [];
@@ -525,17 +623,15 @@ Singleton {
}
function getAppsInCategory(category) {
if (category === I18n.tr("All")) {
return applications;
}
const visibleApps = getVisibleApplications();
if (category === I18n.tr("All"))
return visibleApps;
// Check if it's a plugin category
const pluginItems = getPluginItems(category, "");
if (pluginItems.length > 0) {
if (pluginItems.length > 0)
return pluginItems;
}
return applications.filter(app => {
return visibleApps.filter(app => {
const appCategories = getCategoriesForApp(app);
return appCategories.includes(category);
});