diff --git a/quickshell/Modals/DankLauncherV2/Controller.qml b/quickshell/Modals/DankLauncherV2/Controller.qml index 184f3d83..3b0882cf 100644 --- a/quickshell/Modals/DankLauncherV2/Controller.qml +++ b/quickshell/Modals/DankLauncherV2/Controller.qml @@ -684,12 +684,15 @@ Item { if (searchMode === "all") { if (searchQuery && searchQuery.length >= 2) { _pluginPhasePending = true; - _pluginPhaseForceFirst = shouldResetSelection; - _phase1Items = allItems; + _phase1Items = allItems.slice(); pluginPhaseTimer.restart(); - isSearching = true; - searchCompleted(); - return; + if (allItems.length === 0) { + _pluginPhaseForceFirst = shouldResetSelection; + isSearching = true; + searchCompleted(); + return; + } + _pluginPhaseForceFirst = false; } else if (!searchQuery) { var emptyTriggerOrdered = getEmptyTriggerPluginsOrdered(); for (var i = 0; i < emptyTriggerOrdered.length; i++) { diff --git a/quickshell/Modules/WallpaperBackground.qml b/quickshell/Modules/WallpaperBackground.qml index 174f8185..46dd3070 100644 --- a/quickshell/Modules/WallpaperBackground.qml +++ b/quickshell/Modules/WallpaperBackground.qml @@ -242,7 +242,7 @@ Variants { Image { id: nextWallpaper anchors.fill: parent - visible: true + visible: source !== "" opacity: 0 layer.enabled: false asynchronous: true @@ -512,14 +512,18 @@ Variants { } } - MultiEffect { + Loader { anchors.fill: parent - source: effectLoader.active ? effectLoader.item : currentWallpaper - visible: CompositorService.isNiri && SettingsData.blurWallpaperOnOverview && NiriService.inOverview && currentWallpaper.source !== "" - blurEnabled: true - blur: 0.8 - blurMax: 75 - autoPaddingEnabled: false + active: CompositorService.isNiri && SettingsData.blurWallpaperOnOverview && NiriService.inOverview && currentWallpaper.source !== "" + + sourceComponent: MultiEffect { + anchors.fill: parent + source: effectLoader.active ? effectLoader.item : currentWallpaper + blurEnabled: true + blur: 0.8 + blurMax: 75 + autoPaddingEnabled: false + } } } } diff --git a/quickshell/Services/SettingsSearchService.qml b/quickshell/Services/SettingsSearchService.qml index 7c6d929c..97e5d116 100644 --- a/quickshell/Services/SettingsSearchService.qml +++ b/quickshell/Services/SettingsSearchService.qml @@ -16,6 +16,7 @@ Singleton { property var registeredCards: ({}) property var settingsIndex: [] property bool indexLoaded: false + property var _translatedCache: [] readonly property var conditionMap: ({ "isNiri": () => CompositorService.isNiri, @@ -38,9 +39,11 @@ Singleton { try { root.settingsIndex = JSON.parse(text()); root.indexLoaded = true; + root._rebuildTranslationCache(); } catch (e) { console.warn("SettingsSearchService: Failed to parse index:", e); root.settingsIndex = []; + root._translatedCache = []; } } onLoadFailed: error => console.warn("SettingsSearchService: Failed to load index:", error) @@ -131,6 +134,27 @@ Singleton { }; } + function _rebuildTranslationCache() { + var cache = []; + for (var i = 0; i < settingsIndex.length; i++) { + var item = settingsIndex[i]; + var t = translateItem(item); + cache.push({ + section: t.section, + label: t.label, + tabIndex: t.tabIndex, + category: t.category, + keywords: t.keywords, + icon: t.icon, + description: t.description, + conditionKey: t.conditionKey, + labelLower: t.label.toLowerCase(), + categoryLower: t.category.toLowerCase() + }); + } + _translatedCache = cache; + } + function search(text) { query = text; if (!text) { @@ -138,18 +162,19 @@ Singleton { return; } - const queryLower = text.toLowerCase().trim(); - const queryWords = queryLower.split(/\s+/).filter(w => w.length > 0); - const scored = []; + var queryLower = text.toLowerCase().trim(); + var queryWords = queryLower.split(/\s+/).filter(w => w.length > 0); + var scored = []; + var cache = _translatedCache; - for (const item of settingsIndex) { - if (!checkCondition(item)) + for (var i = 0; i < cache.length; i++) { + var entry = cache[i]; + if (!checkCondition(entry)) continue; - const translated = translateItem(item); - const labelLower = translated.label.toLowerCase(); - const categoryLower = translated.category.toLowerCase(); - let score = 0; + var labelLower = entry.labelLower; + var categoryLower = entry.categoryLower; + var score = 0; if (labelLower === queryLower) { score = 10000; @@ -162,24 +187,32 @@ Singleton { } if (score === 0) { - for (const keyword of item.keywords) { - if (keyword.startsWith(queryLower)) { - score = Math.max(score, 800); + var keywords = entry.keywords; + for (var k = 0; k < keywords.length; k++) { + if (keywords[k].startsWith(queryLower)) { + score = 800; break; } - if (keyword.includes(queryLower)) { - score = Math.max(score, 400); + if (keywords[k].includes(queryLower) && score < 400) { + score = 400; } } } if (score === 0 && queryWords.length > 1) { - let allMatch = true; - for (const word of queryWords) { - const inLabel = labelLower.includes(word); - const inKeywords = item.keywords.some(k => k.includes(word)); - const inCategory = categoryLower.includes(word); - if (!inLabel && !inKeywords && !inCategory) { + var allMatch = true; + for (var w = 0; w < queryWords.length; w++) { + var word = queryWords[w]; + if (labelLower.includes(word)) + continue; + var inKeywords = false; + for (var k = 0; k < entry.keywords.length; k++) { + if (entry.keywords[k].includes(word)) { + inKeywords = true; + break; + } + } + if (!inKeywords && !categoryLower.includes(word)) { allMatch = false; break; } @@ -190,7 +223,7 @@ Singleton { if (score > 0) { scored.push({ - item: translated, + item: entry, score: score }); }