1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

launcher: sort by usage frequency

This commit is contained in:
bbedward
2025-07-24 18:36:23 -04:00
parent 99f17de065
commit 366930fc03
13 changed files with 557 additions and 258 deletions

View File

@@ -145,6 +145,7 @@ PanelWindow {
// Content with focus management
Item {
id: keyHandler
anchors.fill: parent
focus: true
Component.onCompleted: {
@@ -172,10 +173,10 @@ PanelWindow {
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
appLauncher.launchSelected();
event.accepted = true;
} else if (event.text && event.text.length > 0 && event.text.match(/[a-zA-Z0-9\\s]/)) {
} else if (!searchField.activeFocus && event.text && event.text.length > 0 && event.text.match(/[a-zA-Z0-9\\s]/)) {
// User started typing, focus search field and pass the character
searchField.forceActiveFocus();
searchField.text = event.text;
searchField.insertText(event.text);
event.accepted = true;
}
}
@@ -233,17 +234,21 @@ PanelWindow {
font.pixelSize: Theme.fontSizeLarge
enabled: appDrawerPopout.isVisible
placeholderText: "Search applications..."
ignoreLeftRightKeys: true
keyForwardTargets: [keyHandler]
onTextEdited: {
appLauncher.searchQuery = text;
}
Keys.onPressed: function(event) {
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && appLauncher.model.count && text.length > 0) {
// Launch first app when typing in search field
var firstApp = appLauncher.model.get(0);
appLauncher.launchApp(firstApp);
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length > 0) {
if (appLauncher.keyboardNavigationActive && appLauncher.model.count > 0) {
appLauncher.launchSelected();
} else if (appLauncher.model.count > 0) {
var firstApp = appLauncher.model.get(0);
appLauncher.launchApp(firstApp);
}
event.accepted = true;
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || (event.key === Qt.Key_Left && appLauncher.viewMode === "grid") || (event.key === Qt.Key_Right && appLauncher.viewMode === "grid") || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
// Pass navigation keys and enter (when not searching) to main handler
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || event.key === Qt.Key_Left || event.key === Qt.Key_Right || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
event.accepted = false;
}
}

View File

@@ -24,7 +24,7 @@ Item {
var allCategories = AppSearchService.getAllCategories().filter(cat => {
return cat !== "Education" && cat !== "Science";
});
var result = ["All", "Recents"];
var result = ["All"];
return result.concat(allCategories.filter(cat => {
return cat !== "All";
}));
@@ -33,13 +33,8 @@ Item {
// Category icons (computed from AppSearchService)
property var categoryIcons: categories.map(category => AppSearchService.getCategoryIcon(category))
// Recent apps helper
property var recentApps: Prefs.recentlyUsedApps.map(recentApp => {
var app = AppSearchService.getAppByExec(recentApp.exec);
return app && !app.noDisplay ? app : null;
}).filter(app => {
return app !== null;
})
// App usage ranking helper
property var appUsageRanking: Prefs.appUsageRanking
// Signals
signal appLaunched(var app)
@@ -70,10 +65,12 @@ Item {
}
}
onSelectedCategoryChanged: updateFilteredModel()
onAppUsageRankingChanged: updateFilteredModel()
function updateFilteredModel() {
filteredModel.clear();
selectedIndex = 0;
keyboardNavigationActive = false;
var apps = [];
@@ -81,8 +78,6 @@ Item {
// Show apps from category
if (selectedCategory === "All") {
apps = AppSearchService.applications || [];
} else if (selectedCategory === "Recents") {
apps = recentApps;
} else {
var categoryApps = AppSearchService.getAppsInCategory(selectedCategory);
apps = categoryApps.slice(0, maxResults);
@@ -91,16 +86,6 @@ Item {
// Search with category filter
if (selectedCategory === "All") {
apps = AppSearchService.searchApplications(searchQuery);
} else if (selectedCategory === "Recents") {
if (recentApps.length > 0) {
var allSearchResults = AppSearchService.searchApplications(searchQuery);
var recentNames = new Set(recentApps.map(app => app.name));
apps = allSearchResults.filter(searchApp => {
return recentNames.has(searchApp.name);
});
} else {
apps = [];
}
} else {
var categoryApps = AppSearchService.getAppsInCategory(selectedCategory);
if (categoryApps.length > 0) {
@@ -114,6 +99,21 @@ Item {
}
}
}
// Sort apps by usage ranking, then alphabetically
apps = apps.sort(function(a, b) {
var aId = a.id || (a.execString || a.exec || "");
var bId = b.id || (b.execString || b.exec || "");
var aUsage = appUsageRanking[aId] ? appUsageRanking[aId].usageCount : 0;
var bUsage = appUsageRanking[bId] ? appUsageRanking[bId].usageCount : 0;
if (aUsage !== bUsage) {
return bUsage - aUsage; // Higher usage first
}
return (a.name || "").localeCompare(b.name || ""); // Alphabetical fallback
});
// Convert to model format and populate
apps.forEach(app => {
@@ -178,16 +178,14 @@ Item {
}
function launchApp(appData) {
if (appData.desktopEntry) {
Prefs.addRecentApp(appData.desktopEntry);
appData.desktopEntry.execute();
} else {
// Fallback to direct execution
var cleanExec = appData.exec.replace(/%[fFuU]/g, "").trim();
console.log("AppLauncher: Launching app directly:", cleanExec);
Quickshell.execDetached(["sh", "-c", cleanExec]);
if (!appData) {
console.warn("AppLauncher: No app data provided");
return;
}
appData.desktopEntry.execute();
appLaunched(appData);
Prefs.addAppUsage(appData.desktopEntry);
}
// Category management

View File

@@ -58,9 +58,9 @@ Item {
width: parent.width
spacing: Theme.spacingS
// Top row: All, Recents, Development, Graphics (4 items)
// Top row: All, Development, Graphics, Games (4 items)
Row {
property var topRowCategories: ["All", "Recents", "Development", "Graphics"]
property var topRowCategories: ["All", "Development", "Graphics", "Games"]
width: parent.width
spacing: Theme.spacingS