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);
});

View File

@@ -182,17 +182,44 @@ Singleton {
return /[;&|<>()$`\\"']/.test(prefix);
}
function parseEnvVars(envVarsStr) {
if (!envVarsStr || envVarsStr.trim().length === 0)
return {};
const envObj = {};
const pairs = envVarsStr.trim().split(/\s+/);
for (const pair of pairs) {
const eqIndex = pair.indexOf("=");
if (eqIndex > 0) {
const key = pair.substring(0, eqIndex);
const value = pair.substring(eqIndex + 1);
envObj[key] = value;
}
}
return envObj;
}
function launchDesktopEntry(desktopEntry, useNvidia) {
let cmd = desktopEntry.command;
if (useNvidia && nvidiaCommand)
cmd = [nvidiaCommand].concat(cmd);
const appId = desktopEntry.id || desktopEntry.execString || desktopEntry.exec || "";
const override = SessionData.getAppOverride(appId);
if (override?.extraFlags) {
const extraArgs = override.extraFlags.trim().split(/\s+/).filter(arg => arg.length > 0);
cmd = cmd.concat(extraArgs);
}
const userPrefix = SettingsData.launchPrefix?.trim() || "";
const defaultPrefix = Quickshell.env("DMS_DEFAULT_LAUNCH_PREFIX") || "";
const prefix = userPrefix.length > 0 ? userPrefix : defaultPrefix;
const workDir = desktopEntry.workingDirectory || Quickshell.env("HOME");
const cursorEnv = typeof SettingsData.getCursorEnvironment === "function" ? SettingsData.getCursorEnvironment() : {};
const overrideEnv = override?.envVars ? parseEnvVars(override.envVars) : {};
const finalEnv = Object.assign({}, cursorEnv, overrideEnv);
if (desktopEntry.runInTerminal) {
const terminal = Quickshell.env("TERMINAL") || "xterm";
const escapedCmd = cmd.map(arg => escapeShellArg(arg)).join(" ");
@@ -200,7 +227,7 @@ Singleton {
Quickshell.execDetached({
command: [terminal, "-e", "sh", "-c", shellCmd],
workingDirectory: workDir,
environment: cursorEnv
environment: finalEnv
});
return;
}
@@ -210,7 +237,7 @@ Singleton {
Quickshell.execDetached({
command: ["sh", "-c", `${prefix} ${escapedCmd}`],
workingDirectory: workDir,
environment: cursorEnv
environment: finalEnv
});
return;
}
@@ -221,7 +248,7 @@ Singleton {
Quickshell.execDetached({
command: cmd,
workingDirectory: workDir,
environment: cursorEnv
environment: finalEnv
});
}