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

Compare commits

...

4 Commits

Author SHA1 Message Date
bbedward
1280bd047d settings: fix sidebar binding when clicked by emitting signal 2026-01-11 22:43:29 -05:00
bbedward
6f206d7523 dankdash: fix 24H format in weather tab
fixes #1283
2026-01-11 21:45:28 -05:00
bbedward
2e58283859 dgop: use used mem directly from API
- conditionally because it depends on newer dgop
2026-01-11 17:32:36 -05:00
Marcus Ramberg
99a5721fe8 settings: extract tab headings for search (#1333)
* settings: extract tab headings for search

* fix pre-commit

---------

Co-authored-by: bbedward <bbedward@gmail.com>
2026-01-11 17:14:45 -05:00
9 changed files with 731 additions and 81 deletions

1
.gitignore vendored
View File

@@ -109,3 +109,4 @@ bin/
.envrc .envrc
.direnv/ .direnv/
quickshell/dms-plugins quickshell/dms-plugins
__pycache__

View File

@@ -319,8 +319,8 @@ FloatingWindow {
visible: settingsModal.isCompactMode ? settingsModal.menuVisible : true visible: settingsModal.isCompactMode ? settingsModal.menuVisible : true
parentModal: settingsModal parentModal: settingsModal
currentIndex: settingsModal.currentTabIndex currentIndex: settingsModal.currentTabIndex
onCurrentIndexChanged: { onTabChangeRequested: tabIndex => {
settingsModal.currentTabIndex = currentIndex; settingsModal.currentTabIndex = tabIndex;
if (settingsModal.isCompactMode) { if (settingsModal.isCompactMode) {
settingsModal.enableAnimations = true; settingsModal.enableAnimations = true;
settingsModal.menuVisible = false; settingsModal.menuVisible = false;

View File

@@ -15,6 +15,8 @@ Rectangle {
property int currentIndex: 0 property int currentIndex: 0
property var parentModal: null property var parentModal: null
signal tabChangeRequested(int tabIndex)
property var expandedCategories: ({}) property var expandedCategories: ({})
property var autoExpandedCategories: ({}) property var autoExpandedCategories: ({})
property bool searchActive: searchField.text.length > 0 property bool searchActive: searchField.text.length > 0
@@ -55,8 +57,9 @@ Rectangle {
if (keyboardHighlightIndex < 0) if (keyboardHighlightIndex < 0)
return; return;
var oldIndex = currentIndex; var oldIndex = currentIndex;
currentIndex = keyboardHighlightIndex; var newIndex = keyboardHighlightIndex;
autoCollapseIfNeeded(oldIndex, currentIndex); tabChangeRequested(newIndex);
autoCollapseIfNeeded(oldIndex, newIndex);
keyboardHighlightIndex = -1; keyboardHighlightIndex = -1;
Qt.callLater(searchField.forceActiveFocus); Qt.callLater(searchField.forceActiveFocus);
} }
@@ -398,28 +401,32 @@ Rectangle {
var flatItems = getFlatNavigableItems(); var flatItems = getFlatNavigableItems();
var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
var oldIndex = currentIndex; var oldIndex = currentIndex;
var newIndex;
if (currentPos === -1) { if (currentPos === -1) {
currentIndex = flatItems[0]?.tabIndex ?? 0; newIndex = flatItems[0]?.tabIndex ?? 0;
} else { } else {
var nextPos = (currentPos + 1) % flatItems.length; var nextPos = (currentPos + 1) % flatItems.length;
currentIndex = flatItems[nextPos].tabIndex; newIndex = flatItems[nextPos].tabIndex;
} }
autoCollapseIfNeeded(oldIndex, currentIndex); tabChangeRequested(newIndex);
autoExpandForTab(currentIndex); autoCollapseIfNeeded(oldIndex, newIndex);
autoExpandForTab(newIndex);
} }
function navigatePrevious() { function navigatePrevious() {
var flatItems = getFlatNavigableItems(); var flatItems = getFlatNavigableItems();
var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
var oldIndex = currentIndex; var oldIndex = currentIndex;
var newIndex;
if (currentPos === -1) { if (currentPos === -1) {
currentIndex = flatItems[0]?.tabIndex ?? 0; newIndex = flatItems[0]?.tabIndex ?? 0;
} else { } else {
var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length; var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
currentIndex = flatItems[prevPos].tabIndex; newIndex = flatItems[prevPos].tabIndex;
} }
autoCollapseIfNeeded(oldIndex, currentIndex); tabChangeRequested(newIndex);
autoExpandForTab(currentIndex); autoCollapseIfNeeded(oldIndex, newIndex);
autoExpandForTab(newIndex);
} }
function getFlatNavigableItems() { function getFlatNavigableItems() {
@@ -488,7 +495,7 @@ Rectangle {
SettingsSearchService.navigateToSection(result.section); SettingsSearchService.navigateToSection(result.section);
} }
var oldIndex = root.currentIndex; var oldIndex = root.currentIndex;
root.currentIndex = result.tabIndex; tabChangeRequested(result.tabIndex);
autoCollapseIfNeeded(oldIndex, result.tabIndex); autoCollapseIfNeeded(oldIndex, result.tabIndex);
autoExpandForTab(result.tabIndex); autoExpandForTab(result.tabIndex);
searchField.text = ""; searchField.text = "";
@@ -807,7 +814,7 @@ Rectangle {
if (categoryDelegate.modelData.children) { if (categoryDelegate.modelData.children) {
root.toggleCategory(categoryDelegate.modelData.id); root.toggleCategory(categoryDelegate.modelData.id);
} else if (categoryDelegate.modelData.tabIndex !== undefined) { } else if (categoryDelegate.modelData.tabIndex !== undefined) {
root.currentIndex = categoryDelegate.modelData.tabIndex; root.tabChangeRequested(categoryDelegate.modelData.tabIndex);
} }
Qt.callLater(searchField.forceActiveFocus); Qt.callLater(searchField.forceActiveFocus);
} }
@@ -882,7 +889,7 @@ Rectangle {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
root.keyboardHighlightIndex = -1; root.keyboardHighlightIndex = -1;
root.currentIndex = childDelegate.modelData.tabIndex; root.tabChangeRequested(childDelegate.modelData.tabIndex);
Qt.callLater(searchField.forceActiveFocus); Qt.callLater(searchField.forceActiveFocus);
} }
} }

View File

@@ -20,7 +20,19 @@ Rectangle {
} }
} }
readonly property string dateText: (daily ? root.forecastData?.day : root.forecastData?.time) ?? "--" readonly property string dateText: {
if (daily)
return root.forecastData?.day ?? "--";
if (!root.forecastData?.rawTime)
return root.forecastData?.time ?? "--";
try {
const date = new Date(root.forecastData.rawTime);
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
return date.toLocaleTimeString(Qt.locale(), format);
} catch (e) {
return root.forecastData?.time ?? "--";
}
}
readonly property var minTemp: WeatherService.formatTemp(root.forecastData?.tempMin) readonly property var minTemp: WeatherService.formatTemp(root.forecastData?.tempMin)
readonly property var maxTemp: WeatherService.formatTemp(root.forecastData?.tempMax) readonly property var maxTemp: WeatherService.formatTemp(root.forecastData?.tempMax)

View File

@@ -4,7 +4,6 @@ import QtQuick.Shapes
import qs.Common import qs.Common
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
import qs.Modules.DankBar.Widgets
Item { Item {
id: root id: root
@@ -261,7 +260,17 @@ Item {
StyledText { StyledText {
id: sunriseText id: sunriseText
text: WeatherService.weather.sunrise || "" text: {
if (!WeatherService.weather.rawSunrise)
return WeatherService.weather.sunrise || "";
try {
const date = new Date(WeatherService.weather.rawSunrise);
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
return date.toLocaleTimeString(Qt.locale(), format);
} catch (e) {
return WeatherService.weather.sunrise || "";
}
}
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
anchors.left: sunriseIcon.right anchors.left: sunriseIcon.right
@@ -285,7 +294,17 @@ Item {
StyledText { StyledText {
id: sunsetText id: sunsetText
text: WeatherService.weather.sunset || "" text: {
if (!WeatherService.weather.rawSunset)
return WeatherService.weather.sunset || "";
try {
const date = new Date(WeatherService.weather.rawSunset);
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
return date.toLocaleTimeString(Qt.locale(), format);
} catch (e) {
return WeatherService.weather.sunset || "";
}
}
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
anchors.left: sunsetIcon.right anchors.left: sunsetIcon.right
@@ -324,14 +343,14 @@ Item {
break; break;
} }
} }
readonly property var splitDate: Qt.formatDateTime(dateStepper.currentDate, "yyyy.MM.dd.hh.mm.AP").split('.') readonly property var splitDate: Qt.formatDateTime(dateStepper.currentDate, SettingsData.use24HourClock ? "yyyy.MM.dd.HH.mm" : "yyyy.MM.dd.hh.mm.AP").split('.')
Item { Item {
id: dateStepperInner id: dateStepperInner
anchors.fill: parent anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
readonly property var space: Theme.spacingXS readonly property var space: Theme.spacingXS
width: yearStepper.width + monthStepper.width + dayStepper.width + hourStepper.width + minuteStepper.width + suffix.width + 10.5 * space + 2 * dateStepperInnerPadding.width width: yearStepper.width + monthStepper.width + dayStepper.width + hourStepper.width + minuteStepper.width + (suffix.visible ? suffix.width : 0) + 10.5 * space + 2 * dateStepperInnerPadding.width
Item { Item {
id: dateStepperInnerPadding id: dateStepperInnerPadding
@@ -420,13 +439,14 @@ Item {
} }
Rectangle { Rectangle {
id: suffix id: suffix
visible: !SettingsData.use24HourClock
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: minuteStepper.right anchors.left: minuteStepper.right
anchors.leftMargin: 2 * parent.space anchors.leftMargin: 2 * parent.space
StyledText { StyledText {
isMonospace: true isMonospace: true
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
text: dateStepper.splitDate[5] text: dateStepper.splitDate[5] ?? ""
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
x: -Theme.fontSizeSmall / 2 x: -Theme.fontSizeSmall / 2
y: -Theme.fontSizeSmall / 2 y: -Theme.fontSizeSmall / 2

View File

@@ -316,15 +316,16 @@ Singleton {
const totalKB = mem.total || 0; const totalKB = mem.total || 0;
const availableKB = mem.available || 0; const availableKB = mem.available || 0;
const freeKB = mem.free || 0; const freeKB = mem.free || 0;
const usedKB = mem.used !== undefined ? mem.used : (totalKB - availableKB);
totalMemoryMB = totalKB / 1024; totalMemoryMB = totalKB / 1024;
availableMemoryMB = availableKB / 1024; availableMemoryMB = availableKB / 1024;
freeMemoryMB = freeKB / 1024; freeMemoryMB = freeKB / 1024;
usedMemoryMB = totalMemoryMB - availableMemoryMB; usedMemoryMB = usedKB / 1024;
memoryUsage = totalKB > 0 ? ((totalKB - availableKB) / totalKB) * 100 : 0; memoryUsage = mem.usedPercent !== undefined ? mem.usedPercent : (totalKB > 0 ? ((totalKB - availableKB) / totalKB) * 100 : 0);
totalMemoryKB = totalKB; totalMemoryKB = totalKB;
usedMemoryKB = totalKB - availableKB; usedMemoryKB = usedKB;
totalSwapKB = mem.swaptotal || 0; totalSwapKB = mem.swaptotal || 0;
usedSwapKB = (mem.swaptotal || 0) - (mem.swapfree || 0); usedSwapKB = (mem.swaptotal || 0) - (mem.swapfree || 0);

View File

@@ -745,6 +745,7 @@ Singleton {
hourly_forecast.push({ hourly_forecast.push({
"time": formatTime(hourly.time[i]), "time": formatTime(hourly.time[i]),
"rawTime": hourly.time[i],
"temp": Math.round(tempC), "temp": Math.round(tempC),
"tempF": Math.round(tempF), "tempF": Math.round(tempF),
"feelsLike": Math.round(feelsLikeC), "feelsLike": Math.round(feelsLikeC),
@@ -778,7 +779,9 @@ Singleton {
"tempMaxF": Math.round(tempMaxF), "tempMaxF": Math.round(tempMaxF),
"precipitationProbability": Math.round(daily.precipitation_probability_max?.[i] || 0), "precipitationProbability": Math.round(daily.precipitation_probability_max?.[i] || 0),
"sunrise": daily.sunrise?.[i] ? formatTime(daily.sunrise[i]) : "", "sunrise": daily.sunrise?.[i] ? formatTime(daily.sunrise[i]) : "",
"sunset": daily.sunset?.[i] ? formatTime(daily.sunset[i]) : "" "sunset": daily.sunset?.[i] ? formatTime(daily.sunset[i]) : "",
"rawSunrise": daily.sunrise?.[i] || "",
"rawSunset": daily.sunset?.[i] || ""
}); });
} }
} }
@@ -805,6 +808,8 @@ Singleton {
"wind": Math.round(current.wind_speed_10m || 0) + " " + (currentUnits.wind_speed_10m || 'm/s'), "wind": Math.round(current.wind_speed_10m || 0) + " " + (currentUnits.wind_speed_10m || 'm/s'),
"sunrise": formatTime(daily.sunrise?.[0]) || "06:00", "sunrise": formatTime(daily.sunrise?.[0]) || "06:00",
"sunset": formatTime(daily.sunset?.[0]) || "18:00", "sunset": formatTime(daily.sunset?.[0]) || "18:00",
"rawSunrise": daily.sunrise?.[0] || "",
"rawSunset": daily.sunset?.[0] || "",
"uv": 0, "uv": 0,
"pressure": Math.round(current.surface_pressure || 0), "pressure": Math.round(current.surface_pressure || 0),
"precipitationProbability": Math.round(daily.precipitation_probability_max?.[0] || 0), "precipitationProbability": Math.round(daily.precipitation_probability_max?.[0] || 0),

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os
import re import re
import json import json
from collections import Counter
from pathlib import Path from pathlib import Path
ABBREVIATIONS = { ABBREVIATIONS = {
@@ -153,11 +153,49 @@ SEARCHABLE_COMPONENTS = [
"SettingsToggleCard", "SettingsToggleCard",
] ]
STOPWORDS = {
"the",
"and",
"for",
"with",
"from",
"this",
"that",
"are",
"was",
"will",
"can",
"has",
"have",
"been",
"when",
"your",
"use",
"used",
"using",
"instead",
"like",
"such",
"also",
"only",
"which",
"each",
"other",
"some",
"into",
"than",
"then",
"them",
"these",
"those",
}
def enrich_keywords(label, description, category, existing_tags): def enrich_keywords(label, description, category, existing_tags):
keywords = set(existing_tags) keywords = set(existing_tags)
label_lower = label.lower() label_lower = label.lower()
label_words = re.split(r'[\s\-_&/]+', label_lower) label_words = re.split(r"[\s\-_&/]+", label_lower)
keywords.update(w for w in label_words if len(w) > 2) keywords.update(w for w in label_words if len(w) > 2)
for term, aliases in ABBREVIATIONS.items(): for term, aliases in ABBREVIATIONS.items():
@@ -166,7 +204,7 @@ def enrich_keywords(label, description, category, existing_tags):
if description: if description:
desc_lower = description.lower() desc_lower = description.lower()
desc_words = re.split(r'[\s\-_&/,.]+', desc_lower) desc_words = re.split(r"[\s\-_&/,.]+", desc_lower)
keywords.update(w for w in desc_words if len(w) > 3 and w.isalpha()) keywords.update(w for w in desc_words if len(w) > 3 and w.isalpha())
for term, aliases in ABBREVIATIONS.items(): for term, aliases in ABBREVIATIONS.items():
if term in desc_lower: if term in desc_lower:
@@ -176,17 +214,13 @@ def enrich_keywords(label, description, category, existing_tags):
keywords.update(CATEGORY_KEYWORDS[category]) keywords.update(CATEGORY_KEYWORDS[category])
cat_lower = category.lower() cat_lower = category.lower()
cat_words = re.split(r'[\s\-_&/]+', cat_lower) cat_words = re.split(r"[\s\-_&/]+", cat_lower)
keywords.update(w for w in cat_words if len(w) > 2) keywords.update(w for w in cat_words if len(w) > 2)
stopwords = {'the', 'and', 'for', 'with', 'from', 'this', 'that', 'are', 'was', keywords = {k for k in keywords if k not in STOPWORDS and len(k) > 1}
'will', 'can', 'has', 'have', 'been', 'when', 'your', 'use', 'used',
'using', 'instead', 'like', 'such', 'also', 'only', 'which', 'each',
'other', 'some', 'into', 'than', 'then', 'them', 'these', 'those'}
keywords = {k for k in keywords if k not in stopwords and len(k) > 1}
return sorted(keywords) return sorted(keywords)
def extract_i18n_string(value): def extract_i18n_string(value):
match = re.search(r'I18n\.tr\(["\']([^"\']+)["\']', value) match = re.search(r'I18n\.tr\(["\']([^"\']+)["\']', value)
if match: if match:
@@ -196,38 +230,42 @@ def extract_i18n_string(value):
return match.group(1) return match.group(1)
return None return None
def extract_tags(value): def extract_tags(value):
match = re.search(r'\[([^\]]+)\]', value) match = re.search(r"\[([^\]]+)\]", value)
if not match: if not match:
return [] return []
content = match.group(1) content = match.group(1)
tags = re.findall(r'["\']([^"\']+)["\']', content) tags = re.findall(r'["\']([^"\']+)["\']', content)
return tags return tags
def parse_component_block(content, start_pos, component_name): def parse_component_block(content, start_pos, component_name):
brace_count = 0 brace_count = 0
started = False started = False
block_start = start_pos block_start = start_pos
for i in range(start_pos, len(content)): for i in range(start_pos, len(content)):
if content[i] == '{': if content[i] == "{":
if not started: if not started:
block_start = i block_start = i
started = True started = True
brace_count += 1 brace_count += 1
elif content[i] == '}': elif content[i] == "}":
brace_count -= 1 brace_count -= 1
if started and brace_count == 0: if started and brace_count == 0:
return content[block_start:i+1] return content[block_start : i + 1]
return "" return ""
def extract_property(block, prop_name): def extract_property(block, prop_name):
pattern = rf'{prop_name}\s*:\s*([^\n]+)' pattern = rf"{prop_name}\s*:\s*([^\n]+)"
match = re.search(pattern, block) match = re.search(pattern, block)
if match: if match:
return match.group(1).strip() return match.group(1).strip()
return None return None
def find_settings_components(content, filename): def find_settings_components(content, filename):
results = [] results = []
tab_index = TAB_INDEX_MAP.get(filename, -1) tab_index = TAB_INDEX_MAP.get(filename, -1)
@@ -236,7 +274,7 @@ def find_settings_components(content, filename):
return results return results
for component in SEARCHABLE_COMPONENTS: for component in SEARCHABLE_COMPONENTS:
pattern = rf'\b{component}\s*\{{' pattern = rf"\b{component}\s*\{{"
for match in re.finditer(pattern, content): for match in re.finditer(pattern, content):
block = parse_component_block(content, match.start(), component) block = parse_component_block(content, match.start(), component)
if not block: if not block:
@@ -244,7 +282,7 @@ def find_settings_components(content, filename):
setting_key = extract_property(block, "settingKey") setting_key = extract_property(block, "settingKey")
if setting_key: if setting_key:
setting_key = setting_key.strip('"\'') setting_key = setting_key.strip("\"'")
if not setting_key: if not setting_key:
continue continue
@@ -263,7 +301,7 @@ def find_settings_components(content, filename):
icon_raw = extract_property(block, "iconName") icon_raw = extract_property(block, "iconName")
icon = None icon = None
if icon_raw: if icon_raw:
icon = icon_raw.strip('"\'') icon = icon_raw.strip("\"'")
if icon.startswith("{") or "?" in icon: if icon.startswith("{") or "?" in icon:
icon = None icon = None
@@ -321,6 +359,95 @@ def find_settings_components(content, filename):
return results return results
def parse_tabs_from_sidebar(sidebar_file):
with open(sidebar_file, "r", encoding="utf-8") as f:
content = f.read()
pattern = r'"text"\s*:\s*I18n\.tr\("([^"]+)"(?:,\s*"[^"]+")?\).*?"icon"\s*:\s*"([^"]+)".*?"tabIndex"\s*:\s*(\d+)'
tabs = []
for match in re.finditer(pattern, content, re.DOTALL):
label, icon, tab_idx = match.group(1), match.group(2), int(match.group(3))
before_text = content[: match.start()]
parent_match = re.search(
r'"text"\s*:\s*I18n\.tr\("([^"]+)"\)[^{]*"children"[^[]*\[[^{]*$',
before_text,
)
parent = parent_match.group(1) if parent_match else None
cond = None
after_pos = match.end()
snippet = content[match.start() : min(after_pos + 200, len(content))]
for qml_cond, key in [
("shortcutsOnly", "keybindsAvailable"),
("soundsOnly", "soundsAvailable"),
("cupsOnly", "cupsAvailable"),
("dmsOnly", "dmsConnected"),
("hyprlandNiriOnly", "isHyprlandOrNiri"),
("clipboardOnly", "dmsConnected"),
]:
if f'"{qml_cond}": true' in snippet:
cond = key
break
tabs.append(
{
"tabIndex": tab_idx,
"label": label,
"icon": icon,
"parent": parent,
"conditionKey": cond,
}
)
return tabs
def generate_tab_entries(sidebar_file):
tabs = parse_tabs_from_sidebar(sidebar_file)
label_counts = Counter([t["label"] for t in tabs])
entries = []
for tab in tabs:
label = (
f"{tab['parent']}: {tab['label']}"
if label_counts[tab["label"]] > 1 and tab["parent"]
else tab["label"]
)
category = TAB_CATEGORY_MAP.get(tab["tabIndex"], "Settings")
keywords = enrich_keywords(tab["label"], None, category, [])
if tab["parent"]:
parent_keywords = [
w for w in re.split(r"[\s\-_&/]+", tab["parent"].lower()) if len(w) > 2
]
keywords = sorted(
set(
keywords
+ parent_keywords
+ [k for p in parent_keywords for k in ABBREVIATIONS.get(p, [])]
)
)
entry = {
"section": f"_tab_{tab['tabIndex']}",
"label": label,
"tabIndex": tab["tabIndex"],
"category": category,
"keywords": keywords,
"icon": tab["icon"],
}
if tab["conditionKey"]:
entry["conditionKey"] = tab["conditionKey"]
entries.append(entry)
return entries
def extract_settings_index(root_dir): def extract_settings_index(root_dir):
settings_dir = Path(root_dir) / "Modules" / "Settings" settings_dir = Path(root_dir) / "Modules" / "Settings"
all_entries = [] all_entries = []
@@ -330,7 +457,7 @@ def extract_settings_index(root_dir):
if not qml_file.name.endswith("Tab.qml"): if not qml_file.name.endswith("Tab.qml"):
continue continue
with open(qml_file, 'r', encoding='utf-8') as f: with open(qml_file, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
entries = find_settings_components(content, qml_file.name) entries = find_settings_components(content, qml_file.name)
@@ -342,29 +469,37 @@ def extract_settings_index(root_dir):
return all_entries return all_entries
def main(): def main():
script_dir = Path(__file__).parent script_dir = Path(__file__).parent
root_dir = script_dir.parent root_dir = script_dir.parent
sidebar_file = root_dir / "Modals" / "Settings" / "SettingsSidebar.qml"
print("Extracting settings search index...") print("Extracting settings search index...")
entries = extract_settings_index(root_dir) settings_entries = extract_settings_index(root_dir)
tab_entries = generate_tab_entries(sidebar_file)
entries.sort(key=lambda x: (x["tabIndex"], x["label"])) all_entries = tab_entries + settings_entries
all_entries.sort(key=lambda x: (x["tabIndex"], x["label"]))
output_path = script_dir / "settings_search_index.json" output_path = script_dir / "settings_search_index.json"
with open(output_path, 'w', encoding='utf-8') as f: with open(output_path, "w", encoding="utf-8") as f:
json.dump(entries, f, indent=2, ensure_ascii=False) json.dump(all_entries, f, indent=2, ensure_ascii=False)
print(f"Found {len(entries)} searchable settings") print(f"Found {len(settings_entries)} searchable settings")
print(f"Found {len(tab_entries)} tab entries")
print(f"Total: {len(all_entries)} entries")
print(f"Output: {output_path}") print(f"Output: {output_path}")
conditions = set() conditions = set()
for entry in entries: for entry in all_entries:
if "conditionKey" in entry: if "conditionKey" in entry:
conditions.add(entry["conditionKey"]) conditions.add(entry["conditionKey"])
if conditions: if conditions:
print(f"Condition keys found: {', '.join(sorted(conditions))}") print(f"Condition keys found: {', '.join(sorted(conditions))}")
if __name__ == '__main__':
if __name__ == "__main__":
main() main()

View File

@@ -295,6 +295,20 @@
], ],
"description": "Set different wallpapers for each connected monitor" "description": "Set different wallpapers for each connected monitor"
}, },
{
"section": "_tab_0",
"label": "Personalization",
"tabIndex": 0,
"category": "Personalization",
"keywords": [
"appearance",
"custom",
"customize",
"personal",
"personalization"
],
"icon": "palette"
},
{ {
"section": "wallpaperTransition", "section": "wallpaperTransition",
"label": "Transition Effect", "label": "Transition Effect",
@@ -494,6 +508,22 @@
], ],
"description": "Display seconds in the clock" "description": "Display seconds in the clock"
}, },
{
"section": "_tab_1",
"label": "Time & Weather",
"tabIndex": 1,
"category": "Time & Weather",
"keywords": [
"climate",
"clock",
"date",
"forecast",
"temperature",
"time",
"weather"
],
"icon": "schedule"
},
{ {
"section": "timeFormat", "section": "timeFormat",
"label": "Time Format", "label": "Time Format",
@@ -576,6 +606,23 @@
"icon": "cloud", "icon": "cloud",
"description": "Show weather information in top bar and control center" "description": "Show weather information in top bar and control center"
}, },
{
"section": "_tab_2",
"label": "Keyboard Shortcuts",
"tabIndex": 2,
"category": "Keyboard Shortcuts",
"keywords": [
"bindings",
"hotkey",
"hotkeys",
"keybinds",
"keyboard",
"keys",
"shortcuts"
],
"icon": "keyboard",
"conditionKey": "keybindsAvailable"
},
{ {
"section": "barConfigurations", "section": "barConfigurations",
"label": "Bar Configurations", "label": "Bar Configurations",
@@ -614,6 +661,21 @@
], ],
"icon": "rounded_corner" "icon": "rounded_corner"
}, },
{
"section": "_tab_3",
"label": "Dank Bar",
"tabIndex": 3,
"category": "Dank Bar",
"keywords": [
"bar",
"dank",
"panel",
"statusbar",
"taskbar",
"topbar"
],
"icon": "toolbar"
},
{ {
"section": "barDisplay", "section": "barDisplay",
"label": "Display Assignment", "label": "Display Assignment",
@@ -1022,6 +1084,25 @@
"description": "Show workspace index numbers in the top bar workspace switcher", "description": "Show workspace index numbers in the top bar workspace switcher",
"conditionKey": "isNiri" "conditionKey": "isNiri"
}, },
{
"section": "_tab_4",
"label": "Workspaces & Widgets",
"tabIndex": 4,
"category": "Workspaces",
"keywords": [
"components",
"desktop",
"desktops",
"modules",
"spaces",
"virtual",
"virtual desktops",
"widgets",
"workspace",
"workspaces"
],
"icon": "dashboard"
},
{ {
"section": "dockAutoHide", "section": "dockAutoHide",
"label": "Auto-hide Dock", "label": "Auto-hide Dock",
@@ -1080,6 +1161,24 @@
"icon": "border_style", "icon": "border_style",
"description": "Add a border around the dock" "description": "Add a border around the dock"
}, },
{
"section": "_tab_5",
"label": "Dock & Launcher",
"tabIndex": 5,
"category": "Dock",
"keywords": [
"app drawer",
"app menu",
"applications",
"dock",
"launcher",
"launcher bar",
"panel",
"start menu",
"taskbar"
],
"icon": "apps"
},
{ {
"section": "dockPosition", "section": "dockPosition",
"label": "Dock Position", "label": "Dock Position",
@@ -1297,6 +1396,38 @@
], ],
"icon": "opacity" "icon": "opacity"
}, },
{
"section": "_tab_7",
"label": "Network",
"tabIndex": 7,
"category": "Network",
"keywords": [
"connection",
"connectivity",
"ethernet",
"internet",
"network",
"online",
"wi-fi",
"wifi",
"wireless"
],
"icon": "wifi",
"conditionKey": "dmsConnected"
},
{
"section": "_tab_8",
"label": "System",
"tabIndex": 8,
"category": "System",
"keywords": [
"linux",
"os",
"system"
],
"icon": "computer",
"conditionKey": "cupsAvailable"
},
{ {
"section": "launcherLogoBrightness", "section": "launcherLogoBrightness",
"label": "Brightness", "label": "Brightness",
@@ -1421,6 +1552,23 @@
], ],
"icon": "terminal" "icon": "terminal"
}, },
{
"section": "_tab_9",
"label": "Launcher",
"tabIndex": 9,
"category": "Launcher",
"keywords": [
"app drawer",
"app menu",
"applications",
"drawer",
"launcher",
"menu",
"start",
"start menu"
],
"icon": "grid_view"
},
{ {
"section": "launcherLogo", "section": "launcherLogo",
"label": "Launcher Button Logo", "label": "Launcher Button Logo",
@@ -2531,6 +2679,26 @@
], ],
"description": "Force terminal applications to always use dark color schemes" "description": "Force terminal applications to always use dark color schemes"
}, },
{
"section": "_tab_10",
"label": "Theme & Colors",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"colour",
"colours",
"hue",
"look",
"palette",
"scheme",
"style",
"theme",
"tint"
],
"icon": "format_paint"
},
{ {
"section": "themeColor", "section": "themeColor",
"label": "Theme Color", "label": "Theme Color",
@@ -3153,6 +3321,54 @@
"icon": "lock", "icon": "lock",
"description": "If the field is hidden, it will appear as soon as a key is pressed." "description": "If the field is hidden, it will appear as soon as a key is pressed."
}, },
{
"section": "lockScreenNotificationMode",
"label": "Notification Display",
"tabIndex": 11,
"category": "Lock Screen",
"keywords": [
"alert",
"control",
"display",
"information",
"lock",
"lockscreen",
"login",
"monitor",
"notif",
"notification",
"notifications",
"output",
"password",
"privacy",
"screen",
"security",
"shown",
"what"
],
"description": "Control what notification information is shown on the lock screen"
},
{
"section": "_tab_11",
"label": "Power & Security",
"tabIndex": 11,
"category": "Lock Screen",
"keywords": [
"hibernate",
"lock",
"login",
"password",
"power",
"reboot",
"restart",
"screen",
"security",
"shutdown",
"sleep",
"suspend"
],
"icon": "security"
},
{ {
"section": "lockScreenShowPasswordField", "section": "lockScreenShowPasswordField",
"label": "Show Password Field", "label": "Show Password Field",
@@ -3268,6 +3484,35 @@
"time" "time"
] ]
}, },
{
"section": "_tab_12",
"label": "Plugins",
"tabIndex": 12,
"category": "Plugins",
"keywords": [
"addon",
"addons",
"extend",
"extensions",
"plugins",
"widgets"
],
"icon": "extension"
},
{
"section": "_tab_13",
"label": "About",
"tabIndex": 13,
"category": "About",
"keywords": [
"about",
"credits",
"help",
"info",
"version"
],
"icon": "info"
},
{ {
"section": "animationSpeed", "section": "animationSpeed",
"label": "Animation Speed", "label": "Animation Speed",
@@ -3422,6 +3667,22 @@
"icon": "text_fields", "icon": "text_fields",
"description": "Select the font family for UI text" "description": "Select the font family for UI text"
}, },
{
"section": "_tab_14",
"label": "Typography & Motion",
"tabIndex": 14,
"category": "Typography & Motion",
"keywords": [
"animation",
"font",
"fonts",
"motion",
"text",
"typeface",
"typography"
],
"icon": "text_fields"
},
{ {
"section": "soundsEnabled", "section": "soundsEnabled",
"label": "Enable System Sounds", "label": "Enable System Sounds",
@@ -3507,6 +3768,20 @@
], ],
"description": "Select system sound theme" "description": "Select system sound theme"
}, },
{
"section": "_tab_15",
"label": "Sounds",
"tabIndex": 15,
"category": "Sounds",
"keywords": [
"audio",
"effects",
"sfx",
"sounds"
],
"icon": "volume_up",
"conditionKey": "soundsAvailable"
},
{ {
"section": "systemSounds", "section": "systemSounds",
"label": "System Sounds", "label": "System Sounds",
@@ -3569,6 +3844,22 @@
], ],
"description": "Play sound when volume is adjusted" "description": "Play sound when volume is adjusted"
}, },
{
"section": "_tab_16",
"label": "Media Player",
"tabIndex": 16,
"category": "Media Player",
"keywords": [
"audio",
"media",
"mpris",
"music",
"playback",
"player",
"spotify"
],
"icon": "music_note"
},
{ {
"section": "mediaPlayer", "section": "mediaPlayer",
"label": "Media Player Settings", "label": "Media Player Settings",
@@ -3614,6 +3905,28 @@
], ],
"description": "Scroll wheel behavior on media widget" "description": "Scroll wheel behavior on media widget"
}, },
{
"section": "notificationCompactMode",
"label": "Compact",
"tabIndex": 17,
"category": "Notifications",
"keywords": [
"alert",
"alerts",
"cards",
"compact",
"display",
"messages",
"mode",
"notif",
"notification",
"notifications",
"size",
"smaller",
"toast"
],
"description": "Use smaller notification cards"
},
{ {
"section": "notificationHistorySaveCritical", "section": "notificationHistorySaveCritical",
"label": "Critical Priority", "label": "Critical Priority",
@@ -3888,35 +4201,6 @@
], ],
"description": "Timeout for normal priority notifications" "description": "Timeout for normal priority notifications"
}, },
{
"section": "lockScreenNotificationMode",
"label": "Notification Display",
"tabIndex": 17,
"category": "Notifications",
"keywords": [
"alert",
"alerts",
"control",
"display",
"information",
"lock",
"lockscreen",
"login",
"messages",
"monitor",
"notif",
"notification",
"notifications",
"output",
"privacy",
"screen",
"security",
"shown",
"toast",
"what"
],
"description": "Control what notification information is shown on the lock screen"
},
{ {
"section": "notificationOverlayEnabled", "section": "notificationOverlayEnabled",
"label": "Notification Overlay", "label": "Notification Overlay",
@@ -3991,6 +4275,22 @@
"icon": "timer", "icon": "timer",
"description": "Timeout for low priority notifications" "description": "Timeout for low priority notifications"
}, },
{
"section": "_tab_17",
"label": "Notifications",
"tabIndex": 17,
"category": "Notifications",
"keywords": [
"alert",
"alerts",
"messages",
"notif",
"notifications",
"notifs",
"toast"
],
"icon": "notifications"
},
{ {
"section": "notificationPopupPosition", "section": "notificationPopupPosition",
"label": "Popup Position", "label": "Popup Position",
@@ -4015,6 +4315,25 @@
], ],
"description": "Choose where notification popups appear on screen" "description": "Choose where notification popups appear on screen"
}, },
{
"section": "_tab_18",
"label": "On-screen Displays",
"tabIndex": 18,
"category": "On-screen Displays",
"keywords": [
"displays",
"indicator",
"monitor",
"monitors",
"osd",
"output",
"outputs",
"popup",
"screen",
"screens"
],
"icon": "tune"
},
{ {
"section": "osd", "section": "osd",
"label": "On-screen Displays", "label": "On-screen Displays",
@@ -4061,6 +4380,23 @@
], ],
"icon": "find_replace" "icon": "find_replace"
}, },
{
"section": "_tab_19",
"label": "Running Apps",
"tabIndex": 19,
"category": "Running Apps",
"keywords": [
"active",
"apps",
"open",
"running",
"taskbar",
"tasks",
"windows"
],
"icon": "apps",
"conditionKey": "isHyprlandOrNiri"
},
{ {
"section": "runningApps", "section": "runningApps",
"label": "Running Apps Settings", "label": "Running Apps Settings",
@@ -4084,6 +4420,20 @@
"icon": "apps", "icon": "apps",
"description": "Show only apps running in current workspace" "description": "Show only apps running in current workspace"
}, },
{
"section": "_tab_20",
"label": "System Updater",
"tabIndex": 20,
"category": "System Updater",
"keywords": [
"packages",
"system",
"updater",
"updates",
"upgrade"
],
"icon": "refresh"
},
{ {
"section": "systemUpdater", "section": "systemUpdater",
"label": "System Updater", "label": "System Updater",
@@ -4394,6 +4744,23 @@
"timeout" "timeout"
] ]
}, },
{
"section": "_tab_21",
"label": "Power & Sleep",
"tabIndex": 21,
"category": "Power & Sleep",
"keywords": [
"energy",
"hibernate",
"power",
"reboot",
"restart",
"shutdown",
"sleep",
"suspend"
],
"icon": "power_settings_new"
},
{ {
"section": "powerConfirmation", "section": "powerConfirmation",
"label": "Power Action Confirmation", "label": "Power Action Confirmation",
@@ -4536,6 +4903,23 @@
], ],
"description": "Display power menu actions in a grid instead of a list" "description": "Display power menu actions in a grid instead of a list"
}, },
{
"section": "_tab_22",
"label": "Widgets",
"tabIndex": 22,
"category": "Dank Bar",
"keywords": [
"bar",
"components",
"dank",
"modules",
"panel",
"statusbar",
"topbar",
"widgets"
],
"icon": "widgets"
},
{ {
"section": "disabled", "section": "disabled",
"label": "Advanced", "label": "Advanced",
@@ -4600,6 +4984,24 @@
"icon": "settings", "icon": "settings",
"description": "Clear all history when server starts" "description": "Clear all history when server starts"
}, },
{
"section": "_tab_23",
"label": "Clipboard",
"tabIndex": 23,
"category": "System",
"keywords": [
"clipboard",
"cliphist",
"copy",
"history",
"linux",
"os",
"paste",
"system"
],
"icon": "content_paste",
"conditionKey": "dmsConnected"
},
{ {
"section": "maxHistory", "section": "maxHistory",
"label": "History Settings", "label": "History Settings",
@@ -4645,6 +5047,23 @@
], ],
"description": "Maximum size per clipboard entry" "description": "Maximum size per clipboard entry"
}, },
{
"section": "_tab_24",
"label": "Displays",
"tabIndex": 24,
"category": "Displays",
"keywords": [
"displays",
"monitor",
"monitors",
"output",
"outputs",
"resolution",
"screen",
"screens"
],
"icon": "monitor"
},
{ {
"section": "nightModeHighTemperature", "section": "nightModeHighTemperature",
"label": "Day Temperature", "label": "Day Temperature",
@@ -4670,6 +5089,25 @@
], ],
"description": "Color temperature for day time" "description": "Color temperature for day time"
}, },
{
"section": "_tab_25",
"label": "Gamma Control",
"tabIndex": 25,
"category": "Displays",
"keywords": [
"blue light",
"color temperature",
"control",
"displays",
"gamma",
"monitor",
"night light",
"redshift",
"resolution",
"screen"
],
"icon": "brightness_6"
},
{ {
"section": "nightModeTemperature", "section": "nightModeTemperature",
"label": "Night Temperature", "label": "Night Temperature",
@@ -4696,5 +5134,36 @@
"warm" "warm"
], ],
"description": "Color temperature for night mode" "description": "Color temperature for night mode"
},
{
"section": "_tab_26",
"label": "Widgets",
"tabIndex": 26,
"category": "Displays",
"keywords": [
"components",
"displays",
"modules",
"monitor",
"resolution",
"screen",
"widgets"
],
"icon": "widgets"
},
{
"section": "_tab_27",
"label": "Desktop Widgets",
"tabIndex": 27,
"category": "Desktop Widgets",
"keywords": [
"components",
"conky",
"desktop",
"desktop clock",
"modules",
"widgets"
],
"icon": "widgets"
} }
] ]