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

launcher: optimize bindings and filters

This commit is contained in:
bbedward
2026-01-04 11:49:05 -05:00
parent 2e1bed5fb5
commit 151d695212
9 changed files with 250 additions and 279 deletions

View File

@@ -467,6 +467,7 @@ Item {
Item { Item {
width: parent.width width: parent.width
height: parent.height - y height: parent.height - y
opacity: parentModal?.isClosing ? 0 : 1
SpotlightResults { SpotlightResults {
id: resultsView id: resultsView

View File

@@ -3,7 +3,6 @@ import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services
DankModal { DankModal {
id: spotlightModal id: spotlightModal
@@ -18,62 +17,69 @@ DankModal {
property bool spotlightOpen: false property bool spotlightOpen: false
property alias spotlightContent: spotlightContentInstance property alias spotlightContent: spotlightContentInstance
property bool openedFromOverview: false property bool openedFromOverview: false
property bool isClosing: false
function show() { function resetContent() {
openedFromOverview = false; if (!spotlightContent)
spotlightOpen = true; return;
open();
Qt.callLater(() => {
if (spotlightContent && spotlightContent.searchField) {
spotlightContent.searchField.forceActiveFocus();
}
});
}
function showWithQuery(query) {
if (spotlightContent) {
if (spotlightContent.appLauncher) {
spotlightContent.appLauncher.searchQuery = query;
}
if (spotlightContent.searchField) {
spotlightContent.searchField.text = query;
}
}
spotlightOpen = true;
open();
Qt.callLater(() => {
if (spotlightContent && spotlightContent.searchField) {
spotlightContent.searchField.forceActiveFocus();
}
});
}
function hide() {
openedFromOverview = false;
spotlightOpen = false;
close();
}
onDialogClosed: {
if (spotlightContent) {
if (spotlightContent.appLauncher) { if (spotlightContent.appLauncher) {
spotlightContent.appLauncher.searchQuery = ""; spotlightContent.appLauncher.searchQuery = "";
spotlightContent.appLauncher.selectedIndex = 0; spotlightContent.appLauncher.selectedIndex = 0;
spotlightContent.appLauncher.setCategory(I18n.tr("All")); spotlightContent.appLauncher.setCategory(I18n.tr("All"));
} }
if (spotlightContent.fileSearchController) { if (spotlightContent.fileSearchController)
spotlightContent.fileSearchController.reset(); spotlightContent.fileSearchController.reset();
} if (spotlightContent.resetScroll)
if (spotlightContent.resetScroll) {
spotlightContent.resetScroll(); spotlightContent.resetScroll();
} if (spotlightContent.searchField)
if (spotlightContent.searchField) {
spotlightContent.searchField.text = ""; spotlightContent.searchField.text = "";
spotlightContent.searchMode = "apps";
} }
function show() {
openedFromOverview = false;
isClosing = false;
resetContent();
spotlightOpen = true;
if (spotlightContent?.appLauncher)
spotlightContent.appLauncher.ensureInitialized();
open();
Qt.callLater(() => {
if (spotlightContent?.searchField)
spotlightContent.searchField.forceActiveFocus();
});
} }
function showWithQuery(query) {
openedFromOverview = false;
isClosing = false;
resetContent();
spotlightOpen = true;
if (spotlightContent?.appLauncher) {
spotlightContent.appLauncher.ensureInitialized();
spotlightContent.appLauncher.searchQuery = query;
}
if (spotlightContent?.searchField)
spotlightContent.searchField.text = query;
open();
Qt.callLater(() => {
if (spotlightContent?.searchField)
spotlightContent.searchField.forceActiveFocus();
});
}
function hide() {
openedFromOverview = false;
isClosing = true;
spotlightOpen = false;
close();
}
onDialogClosed: {
isClosing = false;
resetContent();
} }
function toggle() { function toggle() {

View File

@@ -52,6 +52,7 @@ DankPopout {
onOpened: { onOpened: {
searchMode = "apps"; searchMode = "apps";
appLauncher.ensureInitialized();
appLauncher.searchQuery = ""; appLauncher.searchQuery = "";
appLauncher.selectedIndex = 0; appLauncher.selectedIndex = 0;
appLauncher.setCategory(I18n.tr("All")); appLauncher.setCategory(I18n.tr("All"));
@@ -344,7 +345,7 @@ DankPopout {
width: parent.width - Theme.spacingS * 2 width: parent.width - Theme.spacingS * 2
height: 40 height: 40
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: searchField.text.length === 0 && appDrawerPopout.searchMode === "apps" visible: appDrawerPopout.searchMode === "apps"
Rectangle { Rectangle {
width: 180 width: 180
@@ -404,7 +405,7 @@ DankPopout {
height: { height: {
let usedHeight = 40 + Theme.spacingS; let usedHeight = 40 + Theme.spacingS;
usedHeight += 52 + Theme.spacingS; usedHeight += 52 + Theme.spacingS;
usedHeight += (searchField.text.length === 0 && appDrawerPopout.searchMode === "apps" ? 40 : 0); usedHeight += appDrawerPopout.searchMode === "apps" ? 40 : 0;
return parent.height - usedHeight; return parent.height - usedHeight;
} }
radius: Theme.cornerRadius radius: Theme.cornerRadius

View File

@@ -1,9 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Controls
import Quickshell import Quickshell
import qs.Common import qs.Common
import qs.Services import qs.Services
import qs.Widgets
Item { Item {
id: root id: root
@@ -23,15 +21,15 @@ Item {
property bool keyboardNavigationActive: false property bool keyboardNavigationActive: false
property bool suppressUpdatesWhileLaunching: false property bool suppressUpdatesWhileLaunching: false
property var categories: { property var categories: {
const allCategories = AppSearchService.getAllCategories().filter(cat => cat !== "Education" && cat !== "Science") const allCategories = AppSearchService.getAllCategories().filter(cat => cat !== "Education" && cat !== "Science");
const result = [I18n.tr("All")] const result = [I18n.tr("All")];
return result.concat(allCategories.filter(cat => cat !== I18n.tr("All"))) return result.concat(allCategories.filter(cat => cat !== I18n.tr("All")));
} }
readonly property var categoryIcons: categories.map(category => AppSearchService.getCategoryIcon(category)) readonly property var categoryIcons: categories.map(category => AppSearchService.getCategoryIcon(category))
property var appUsageRanking: AppUsageHistoryData.appUsageRanking || {} property var appUsageRanking: AppUsageHistoryData.appUsageRanking || {}
property alias model: filteredModel property alias model: filteredModel
property var _watchApplications: AppSearchService.applications
property var _uniqueApps: [] property var _uniqueApps: []
property bool _initialized: false
property bool _isTriggered: false property bool _isTriggered: false
property string _triggeredCategory: "" property string _triggeredCategory: ""
property bool _updatingFromTrigger: false property bool _updatingFromTrigger: false
@@ -40,98 +38,109 @@ Item {
signal categorySelected(string category) signal categorySelected(string category)
signal viewModeSelected(string mode) signal viewModeSelected(string mode)
function ensureInitialized() {
if (_initialized)
return;
_initialized = true;
updateFilteredModel();
}
function updateCategories() { function updateCategories() {
const allCategories = AppSearchService.getAllCategories().filter(cat => cat !== "Education" && cat !== "Science") const allCategories = AppSearchService.getAllCategories().filter(cat => cat !== "Education" && cat !== "Science");
const result = [I18n.tr("All")] const result = [I18n.tr("All")];
categories = result.concat(allCategories.filter(cat => cat !== I18n.tr("All"))) categories = result.concat(allCategories.filter(cat => cat !== I18n.tr("All")));
} }
Connections { Connections {
target: PluginService target: PluginService
function onPluginLoaded() { updateCategories() } function onPluginLoaded() {
function onPluginUnloaded() { updateCategories() } updateCategories();
function onPluginListUpdated() { updateCategories() } }
function onPluginUnloaded() {
updateCategories();
}
function onPluginListUpdated() {
updateCategories();
}
function onRequestLauncherUpdate(pluginId) { function onRequestLauncherUpdate(pluginId) {
// Only update if we are actually looking at this plugin or in All category // Only update if we are actually looking at this plugin or in All category
updateFilteredModel() updateFilteredModel();
} }
} }
Connections { Connections {
target: SettingsData target: SettingsData
function onSortAppsAlphabeticallyChanged() { function onSortAppsAlphabeticallyChanged() {
updateFilteredModel() updateFilteredModel();
} }
} }
function updateFilteredModel() { function updateFilteredModel() {
if (suppressUpdatesWhileLaunching) { if (suppressUpdatesWhileLaunching) {
suppressUpdatesWhileLaunching = false suppressUpdatesWhileLaunching = false;
return return;
} }
filteredModel.clear() filteredModel.clear();
selectedIndex = 0 selectedIndex = 0;
keyboardNavigationActive = false keyboardNavigationActive = false;
const triggerResult = checkPluginTriggers(searchQuery) const triggerResult = checkPluginTriggers(searchQuery);
if (triggerResult.triggered) { if (triggerResult.triggered) {
console.log("AppLauncher: Plugin trigger detected:", triggerResult.trigger, "for plugin:", triggerResult.pluginId) console.log("AppLauncher: Plugin trigger detected:", triggerResult.trigger, "for plugin:", triggerResult.pluginId);
} }
let apps = [] let apps = [];
const allCategory = I18n.tr("All") const allCategory = I18n.tr("All");
const emptyTriggerPlugins = typeof PluginService !== "undefined" ? PluginService.getPluginsWithEmptyTrigger() : [] const emptyTriggerPlugins = typeof PluginService !== "undefined" ? PluginService.getPluginsWithEmptyTrigger() : [];
if (triggerResult.triggered) { if (triggerResult.triggered) {
_isTriggered = true _isTriggered = true;
_triggeredCategory = triggerResult.pluginCategory _triggeredCategory = triggerResult.pluginCategory;
_updatingFromTrigger = true _updatingFromTrigger = true;
selectedCategory = triggerResult.pluginCategory selectedCategory = triggerResult.pluginCategory;
_updatingFromTrigger = false _updatingFromTrigger = false;
apps = AppSearchService.getPluginItems(triggerResult.pluginCategory, triggerResult.query) apps = AppSearchService.getPluginItems(triggerResult.pluginCategory, triggerResult.query);
} else { } else {
if (_isTriggered) { if (_isTriggered) {
_updatingFromTrigger = true _updatingFromTrigger = true;
selectedCategory = allCategory selectedCategory = allCategory;
_updatingFromTrigger = false _updatingFromTrigger = false;
_isTriggered = false _isTriggered = false;
_triggeredCategory = "" _triggeredCategory = "";
} }
if (searchQuery.length === 0) { if (searchQuery.length === 0) {
if (selectedCategory === allCategory) { if (selectedCategory === allCategory) {
let emptyTriggerItems = [] let emptyTriggerItems = [];
emptyTriggerPlugins.forEach(pluginId => { emptyTriggerPlugins.forEach(pluginId => {
const plugin = PluginService.getLauncherPlugin(pluginId) const plugin = PluginService.getLauncherPlugin(pluginId);
const pluginCategory = plugin.name || pluginId const pluginCategory = plugin.name || pluginId;
const items = AppSearchService.getPluginItems(pluginCategory, "") const items = AppSearchService.getPluginItems(pluginCategory, "");
emptyTriggerItems = emptyTriggerItems.concat(items) emptyTriggerItems = emptyTriggerItems.concat(items);
}) });
apps = AppSearchService.applications.concat(emptyTriggerItems) apps = AppSearchService.applications.concat(emptyTriggerItems);
} else { } else {
apps = AppSearchService.getAppsInCategory(selectedCategory).slice(0, maxResults) apps = AppSearchService.getAppsInCategory(selectedCategory).slice(0, maxResults);
} }
} else { } else {
if (selectedCategory === allCategory) { if (selectedCategory === allCategory) {
apps = AppSearchService.searchApplications(searchQuery) apps = AppSearchService.searchApplications(searchQuery);
let emptyTriggerItems = [] let emptyTriggerItems = [];
emptyTriggerPlugins.forEach(pluginId => { emptyTriggerPlugins.forEach(pluginId => {
const plugin = PluginService.getLauncherPlugin(pluginId) const plugin = PluginService.getLauncherPlugin(pluginId);
const pluginCategory = plugin.name || pluginId const pluginCategory = plugin.name || pluginId;
const items = AppSearchService.getPluginItems(pluginCategory, searchQuery) const items = AppSearchService.getPluginItems(pluginCategory, searchQuery);
emptyTriggerItems = emptyTriggerItems.concat(items) emptyTriggerItems = emptyTriggerItems.concat(items);
}) });
apps = apps.concat(emptyTriggerItems) apps = apps.concat(emptyTriggerItems);
} else { } else {
const categoryApps = AppSearchService.getAppsInCategory(selectedCategory) const categoryApps = AppSearchService.getAppsInCategory(selectedCategory);
if (categoryApps.length > 0) { if (categoryApps.length > 0) {
const allSearchResults = AppSearchService.searchApplications(searchQuery) const allSearchResults = AppSearchService.searchApplications(searchQuery);
const categoryNames = new Set(categoryApps.map(app => app.name)) const categoryNames = new Set(categoryApps.map(app => app.name));
apps = allSearchResults.filter(searchApp => categoryNames.has(searchApp.name)).slice(0, maxResults) apps = allSearchResults.filter(searchApp => categoryNames.has(searchApp.name)).slice(0, maxResults);
} else { } else {
apps = [] apps = [];
} }
} }
} }
@@ -140,34 +149,34 @@ Item {
if (searchQuery.length === 0) { if (searchQuery.length === 0) {
if (SettingsData.sortAppsAlphabetically) { if (SettingsData.sortAppsAlphabetically) {
apps = apps.sort((a, b) => { apps = apps.sort((a, b) => {
return (a.name || "").localeCompare(b.name || "") return (a.name || "").localeCompare(b.name || "");
}) });
} else { } else {
apps = apps.sort((a, b) => { apps = apps.sort((a, b) => {
const aId = a.id || a.execString || a.exec || "" const aId = a.id || a.execString || a.exec || "";
const bId = b.id || b.execString || b.exec || "" const bId = b.id || b.execString || b.exec || "";
const aUsage = appUsageRanking[aId] ? appUsageRanking[aId].usageCount : 0 const aUsage = appUsageRanking[aId] ? appUsageRanking[aId].usageCount : 0;
const bUsage = appUsageRanking[bId] ? appUsageRanking[bId].usageCount : 0 const bUsage = appUsageRanking[bId] ? appUsageRanking[bId].usageCount : 0;
if (aUsage !== bUsage) { if (aUsage !== bUsage) {
return bUsage - aUsage return bUsage - aUsage;
} }
return (a.name || "").localeCompare(b.name || "") return (a.name || "").localeCompare(b.name || "");
}) });
} }
} }
const seenNames = new Set() const seenNames = new Set();
const uniqueApps = [] const uniqueApps = [];
apps.forEach(app => { apps.forEach(app => {
if (app) { if (app) {
const itemKey = app.name + "|" + (app.execString || app.exec || app.action || "") const itemKey = app.name + "|" + (app.execString || app.exec || app.action || "");
if (seenNames.has(itemKey)) { if (seenNames.has(itemKey)) {
return return;
} }
seenNames.add(itemKey) seenNames.add(itemKey);
uniqueApps.push(app) uniqueApps.push(app);
const isPluginItem = app.action !== undefined const isPluginItem = app.action !== undefined;
filteredModel.append({ filteredModel.append({
"name": app.name || "", "name": app.name || "",
"exec": app.execString || app.exec || app.action || "", "exec": app.execString || app.exec || app.action || "",
@@ -176,102 +185,114 @@ Item {
"categories": app.categories || [], "categories": app.categories || [],
"isPlugin": isPluginItem, "isPlugin": isPluginItem,
"appIndex": uniqueApps.length - 1 "appIndex": uniqueApps.length - 1
}) });
} }
}) });
root._uniqueApps = uniqueApps root._uniqueApps = uniqueApps;
} }
function selectNext() { function selectNext() {
if (filteredModel.count === 0) { if (filteredModel.count === 0) {
return return;
} }
keyboardNavigationActive = true keyboardNavigationActive = true;
selectedIndex = viewMode === "grid" ? Math.min(selectedIndex + gridColumns, filteredModel.count - 1) : Math.min(selectedIndex + 1, filteredModel.count - 1) selectedIndex = viewMode === "grid" ? Math.min(selectedIndex + gridColumns, filteredModel.count - 1) : Math.min(selectedIndex + 1, filteredModel.count - 1);
} }
function selectPrevious() { function selectPrevious() {
if (filteredModel.count === 0) { if (filteredModel.count === 0) {
return return;
} }
keyboardNavigationActive = true keyboardNavigationActive = true;
selectedIndex = viewMode === "grid" ? Math.max(selectedIndex - gridColumns, 0) : Math.max(selectedIndex - 1, 0) selectedIndex = viewMode === "grid" ? Math.max(selectedIndex - gridColumns, 0) : Math.max(selectedIndex - 1, 0);
} }
function selectNextInRow() { function selectNextInRow() {
if (filteredModel.count === 0 || viewMode !== "grid") { if (filteredModel.count === 0 || viewMode !== "grid") {
return return;
} }
keyboardNavigationActive = true keyboardNavigationActive = true;
selectedIndex = Math.min(selectedIndex + 1, filteredModel.count - 1) selectedIndex = Math.min(selectedIndex + 1, filteredModel.count - 1);
} }
function selectPreviousInRow() { function selectPreviousInRow() {
if (filteredModel.count === 0 || viewMode !== "grid") { if (filteredModel.count === 0 || viewMode !== "grid") {
return return;
} }
keyboardNavigationActive = true keyboardNavigationActive = true;
selectedIndex = Math.max(selectedIndex - 1, 0) selectedIndex = Math.max(selectedIndex - 1, 0);
} }
function launchSelected() { function launchSelected() {
if (filteredModel.count === 0 || selectedIndex < 0 || selectedIndex >= filteredModel.count) { if (filteredModel.count === 0 || selectedIndex < 0 || selectedIndex >= filteredModel.count) {
return return;
} }
const selectedApp = filteredModel.get(selectedIndex) const selectedApp = filteredModel.get(selectedIndex);
launchApp(selectedApp) launchApp(selectedApp);
} }
function launchApp(appData) { function launchApp(appData) {
if (!appData || typeof appData.appIndex === "undefined" || appData.appIndex < 0 || appData.appIndex >= _uniqueApps.length) { if (!appData || typeof appData.appIndex === "undefined" || appData.appIndex < 0 || appData.appIndex >= _uniqueApps.length) {
return return;
} }
suppressUpdatesWhileLaunching = true suppressUpdatesWhileLaunching = true;
const actualApp = _uniqueApps[appData.appIndex] const actualApp = _uniqueApps[appData.appIndex];
if (appData.isPlugin) { if (appData.isPlugin) {
const pluginId = getPluginIdForItem(actualApp) const pluginId = getPluginIdForItem(actualApp);
if (pluginId) { if (pluginId) {
AppSearchService.executePluginItem(actualApp, pluginId) AppSearchService.executePluginItem(actualApp, pluginId);
appLaunched(appData) appLaunched(appData);
return return;
} }
} else { } else {
SessionService.launchDesktopEntry(actualApp) SessionService.launchDesktopEntry(actualApp);
appLaunched(appData) appLaunched(appData);
AppUsageHistoryData.addAppUsage(actualApp) AppUsageHistoryData.addAppUsage(actualApp);
} }
} }
function setCategory(category) { function setCategory(category) {
selectedCategory = category selectedCategory = category;
categorySelected(category) categorySelected(category);
} }
function setViewMode(mode) { function setViewMode(mode) {
viewMode = mode viewMode = mode;
viewModeSelected(mode) viewModeSelected(mode);
} }
onSearchQueryChanged: { onSearchQueryChanged: {
if (!_initialized)
return;
if (debounceSearch) { if (debounceSearch) {
searchDebounceTimer.restart() searchDebounceTimer.restart();
} else { } else {
updateFilteredModel() updateFilteredModel();
} }
} }
onSelectedCategoryChanged: { onSelectedCategoryChanged: {
if (_updatingFromTrigger) { if (_updatingFromTrigger || !_initialized)
return return;
updateFilteredModel();
} }
updateFilteredModel()
onAppUsageRankingChanged: {
if (_initialized)
updateFilteredModel();
}
Connections {
target: DesktopEntries
function onApplicationsChanged() {
if (!root._initialized)
return;
root.updateCategories();
root.updateFilteredModel();
} }
onAppUsageRankingChanged: updateFilteredModel()
on_WatchApplicationsChanged: updateFilteredModel()
Component.onCompleted: {
updateFilteredModel()
} }
ListModel { ListModel {
@@ -289,59 +310,67 @@ Item {
// Plugin trigger system functions // Plugin trigger system functions
function checkPluginTriggers(query) { function checkPluginTriggers(query) {
if (!query || typeof PluginService === "undefined") { if (!query || typeof PluginService === "undefined") {
return { triggered: false, pluginCategory: "", query: "" } return {
triggered: false,
pluginCategory: "",
query: ""
};
} }
const triggers = PluginService.getAllPluginTriggers() const triggers = PluginService.getAllPluginTriggers();
for (const trigger in triggers) { for (const trigger in triggers) {
if (query.startsWith(trigger)) { if (query.startsWith(trigger)) {
const pluginId = triggers[trigger] const pluginId = triggers[trigger];
const plugin = PluginService.getLauncherPlugin(pluginId) const plugin = PluginService.getLauncherPlugin(pluginId);
if (plugin) { if (plugin) {
const remainingQuery = query.substring(trigger.length).trim() const remainingQuery = query.substring(trigger.length).trim();
const result = { const result = {
triggered: true, triggered: true,
pluginId: pluginId, pluginId: pluginId,
pluginCategory: plugin.name || pluginId, pluginCategory: plugin.name || pluginId,
query: remainingQuery, query: remainingQuery,
trigger: trigger trigger: trigger
} };
return result return result;
} }
} }
} }
return { triggered: false, pluginCategory: "", query: "" } return {
triggered: false,
pluginCategory: "",
query: ""
};
} }
function getPluginIdForItem(item) { function getPluginIdForItem(item) {
if (!item || !item.categories || typeof PluginService === "undefined") { if (!item || !item.categories || typeof PluginService === "undefined") {
return null return null;
} }
const launchers = PluginService.getLauncherPlugins() const launchers = PluginService.getLauncherPlugins();
for (const pluginId in launchers) { for (const pluginId in launchers) {
const plugin = launchers[pluginId] const plugin = launchers[pluginId];
const pluginCategory = plugin.name || pluginId const pluginCategory = plugin.name || pluginId;
let hasCategory = false let hasCategory = false;
if (Array.isArray(item.categories)) { if (Array.isArray(item.categories)) {
hasCategory = item.categories.includes(pluginCategory) hasCategory = item.categories.includes(pluginCategory);
} else if (item.categories && typeof item.categories.count !== "undefined") { } else if (item.categories && typeof item.categories.count !== "undefined") {
for (let i = 0; i < item.categories.count; i++) { for (let i = 0; i < item.categories.count; i++) {
if (item.categories.get(i) === pluginCategory) { if (item.categories.get(i) === pluginCategory) {
hasCategory = true hasCategory = true;
break break;
} }
} }
} }
if (hasCategory) { if (hasCategory) {
return pluginId return pluginId;
} }
} }
return null return null;
} }
} }

View File

@@ -125,7 +125,12 @@ Scope {
} }
onShouldShowSpotlightChanged: { onShouldShowSpotlightChanged: {
if (shouldShowSpotlight || !isActiveScreen) if (shouldShowSpotlight) {
if (spotlightContent?.appLauncher)
spotlightContent.appLauncher.ensureInitialized();
return;
}
if (!isActiveScreen)
return; return;
Qt.callLater(() => keyboardFocusScope.forceActiveFocus()); Qt.callLater(() => keyboardFocusScope.forceActiveFocus());
} }

View File

@@ -8,7 +8,8 @@ import qs.Common
Singleton { Singleton {
id: root id: root
property var applications: DesktopEntries.applications.values.filter(app => !app.noDisplay) property var applications: []
property var _cachedCategories: null
readonly property int maxResults: 10 readonly property int maxResults: 10
readonly property int frecencySampleSize: 10 readonly property int frecencySampleSize: 10
@@ -36,6 +37,20 @@ Singleton {
} }
] ]
function refreshApplications() {
applications = DesktopEntries.applications.values;
_cachedCategories = null;
}
Connections {
target: DesktopEntries
function onApplicationsChanged() {
root.refreshApplications();
}
}
Component.onCompleted: refreshApplications()
function tokenize(text) { function tokenize(text) {
return text.toLowerCase().trim().split(/[\s\-_]+/).filter(w => w.length > 0); return text.toLowerCase().trim().split(/[\s\-_]+/).filter(w => w.length > 0);
} }
@@ -316,19 +331,20 @@ Singleton {
} }
function getAllCategories() { function getAllCategories() {
const categories = new Set([I18n.tr("All")]); if (_cachedCategories)
return _cachedCategories;
const categories = new Set([I18n.tr("All")]);
for (const app of applications) { for (const app of applications) {
const appCategories = getCategoriesForApp(app); const appCategories = getCategoriesForApp(app);
appCategories.forEach(cat => categories.add(cat)); appCategories.forEach(cat => categories.add(cat));
} }
// Add plugin categories
const pluginCategories = getPluginCategories(); const pluginCategories = getPluginCategories();
pluginCategories.forEach(cat => categories.add(cat)); pluginCategories.forEach(cat => categories.add(cat));
const result = Array.from(categories).sort(); _cachedCategories = Array.from(categories).sort();
return result; return _cachedCategories;
} }
function getAppsInCategory(category) { function getAppsInCategory(category) {

View File

@@ -1,86 +0,0 @@
const vscode = require("vscode");
const path = require("path");
const fs = require("fs");
let watcher = null;
let reloadTimeout = null;
function activate(context) {
const themesDir = path.join(context.extensionPath, "themes");
try {
watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(themesDir, "*.json")
);
} catch (e) {
return;
}
if (!watcher) return;
const reloadTheme = () => {
if (reloadTimeout) clearTimeout(reloadTimeout);
reloadTimeout = setTimeout(async () => {
const config = vscode.workspace.getConfiguration("workbench");
const currentTheme = config.get("colorTheme");
if (!currentTheme?.includes("DankShell")) return;
let themeFile;
switch (true) {
case currentTheme.includes("Light"):
themeFile = path.join(themesDir, "dankshell-light.json");
break;
case currentTheme.includes("Dark"):
themeFile = path.join(themesDir, "dankshell-dark.json");
break;
default:
themeFile = path.join(themesDir, "dankshell-default.json");
}
let themeData;
try {
const content = fs.readFileSync(themeFile, "utf8");
themeData = JSON.parse(content);
} catch (e) {
return;
}
const themeKey = `[${currentTheme}]`;
if (themeData.colors) {
const colorConfig = config.get("colorCustomizations") || {};
colorConfig[themeKey] = themeData.colors;
await config.update(
"colorCustomizations",
colorConfig,
vscode.ConfigurationTarget.Global
);
}
if (themeData.tokenColors) {
const editorConfig = vscode.workspace.getConfiguration("editor");
const tokenConfig = editorConfig.get("tokenColorCustomizations") || {};
tokenConfig[themeKey] = { textMateRules: themeData.tokenColors };
await editorConfig.update(
"tokenColorCustomizations",
tokenConfig,
vscode.ConfigurationTarget.Global
);
}
}, 150);
};
watcher.onDidChange(reloadTheme);
watcher.onDidCreate(reloadTheme);
context.subscriptions.push(watcher);
}
function deactivate() {
if (reloadTimeout) clearTimeout(reloadTimeout);
if (watcher) watcher.dispose();
}
module.exports = { activate, deactivate };

View File

@@ -7,10 +7,6 @@
"engines": { "engines": {
"vscode": "^1.70.0" "vscode": "^1.70.0"
}, },
"main": "./extension.js",
"activationEvents": [
"onStartupFinished"
],
"categories": [ "categories": [
"Themes" "Themes"
], ],
@@ -31,17 +27,20 @@
{ {
"label": "Dynamic Base16 DankShell", "label": "Dynamic Base16 DankShell",
"uiTheme": "vs-dark", "uiTheme": "vs-dark",
"path": "./themes/dankshell-default.json" "path": "./themes/dankshell-default.json",
"_watch": true
}, },
{ {
"label": "Dynamic Base16 DankShell (Dark)", "label": "Dynamic Base16 DankShell (Dark)",
"uiTheme": "vs-dark", "uiTheme": "vs-dark",
"path": "./themes/dankshell-dark.json" "path": "./themes/dankshell-dark.json",
"_watch": true
}, },
{ {
"label": "Dynamic Base16 DankShell (Light)", "label": "Dynamic Base16 DankShell (Light)",
"uiTheme": "vs", "uiTheme": "vs",
"path": "./themes/dankshell-light.json" "path": "./themes/dankshell-light.json",
"_watch": true
} }
] ]
} }