diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-17 10:43:38 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-17 10:43:38 +0200 |
| commit | 166d638bce081631705687501020725045920e50 (patch) | |
| tree | 0f89277d6fcc34f9f4345ed75769001c023c7cd3 /desktop | |
| parent | 4acf7325d8aa7e841c0059211d908d31d492f828 (diff) | |
| download | quickshell-166d638bce081631705687501020725045920e50.tar.gz quickshell-166d638bce081631705687501020725045920e50.zip | |
settings: the sidebar is grouped
Ten pages in one flat list had stopped reading as a list. A module now
names its group, and the sidebar sorts by it and draws a small heading
where it changes: Account (user, git), Appearance (wallpaper, theme,
icons), Desktop (HyprSunset, HyprIdle, autostart) and Assistant (the
daemon, Ask presets). Groups keep the order their first page is
declared in, so shell.qml's module order still decides.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/Module.qml | 4 | ||||
| -rw-r--r-- | desktop/README.md | 2 | ||||
| -rw-r--r-- | desktop/Settings.qml | 91 | ||||
| -rw-r--r-- | desktop/modules/appearance/IconsModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/appearance/IdleModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/appearance/SunsetModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/appearance/ThemeModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/appearance/WallpaperModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/assistant/AssistantModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/assistant/PresetsModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/autostart/AutostartModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/git/GitModule.qml | 1 | ||||
| -rw-r--r-- | desktop/modules/user/UserModule.qml | 1 |
13 files changed, 74 insertions, 33 deletions
diff --git a/desktop/Module.qml b/desktop/Module.qml index a1817a4..85f924b 100644 --- a/desktop/Module.qml +++ b/desktop/Module.qml @@ -42,6 +42,10 @@ QtObject { // things set once and left alone. Such a module has no tile by default. property bool settings: false + // The heading a settings page is listed under in the window's sidebar. + // Groups appear in the order their first module is declared. + property string group: "" + // Words the settings window's search matches besides the label: the // settings buried inside the page, which is not loaded until opened. property list<string> keywords: [] diff --git a/desktop/README.md b/desktop/README.md index a9d62df..59983a9 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -88,6 +88,8 @@ drawer needs to show it: module has no tile. - `keywords`: for a settings page, the words its search should find besides the label. +- `group`: the heading a settings page is listed under in the sidebar. + Groups keep the order their first page is declared in. - `activate()`: what a tile with no page does when clicked. - `alwaysActive`: declares whether the module's service is meant to run while the drawer is closed. The drawer does not read it, the module implements its diff --git a/desktop/Settings.qml b/desktop/Settings.qml index e8895a4..dd376c7 100644 --- a/desktop/Settings.qml +++ b/desktop/Settings.qml @@ -24,11 +24,17 @@ Scope { property bool open: false property string page: "" + // Grouped: a group's pages together, groups in the order their first + // page is declared, pages in declaration order within a group. readonly property var pages: { const out = []; for (let i = 0; i < root.modules.length; i++) if (root.modules[i].settings) out.push(root.modules[i]); - return out; + const order = []; + for (const m of out) if (!order.includes(m.group)) order.push(m.group); + return out.map((m, i) => ({ m, i })) + .sort((a, b) => order.indexOf(a.m.group) - order.indexOf(b.m.group) || a.i - b.i) + .map(x => x.m); } property string query: "" @@ -166,48 +172,67 @@ Scope { spacing: 4 model: root.found - delegate: Rectangle { - id: entry + // A group's heading above its first entry, then the entry. + delegate: Column { + id: slot required property var modelData - readonly property bool selected: root.current === modelData.mod && modelData.key === "" + required property int index width: side.width - height: modelData.hit ? 46 : 36 - radius: 8 - color: selected ? Qt.alpha(Theme.accent, 0.22) - : area.containsMouse ? Qt.alpha(Theme.text, 0.06) : "transparent" Text { - id: entryIcon - anchors { left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter } - text: entry.modelData.mod.icon - font { family: Theme.iconFamily; pixelSize: Theme.fontSize } - color: Theme.text + visible: slot.modelData.mod.group !== "" + && (slot.index === 0 || root.found[slot.index - 1].mod.group !== slot.modelData.mod.group) + leftPadding: 10 + topPadding: slot.index === 0 ? 4 : 14 + bottomPadding: 4 + text: slot.modelData.mod.group.toUpperCase() + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 5; bold: true; letterSpacing: 1 } + color: Theme.overlay } - Column { - anchors { left: entryIcon.right; leftMargin: 10; right: parent.right; rightMargin: 8 - verticalCenter: parent.verticalCenter } + + Rectangle { + id: entry + readonly property var modelData: slot.modelData + readonly property bool selected: root.current === modelData.mod && modelData.key === "" + width: side.width + height: modelData.hit ? 46 : 36 + radius: 8 + color: selected ? Qt.alpha(Theme.accent, 0.22) + : area.containsMouse ? Qt.alpha(Theme.text, 0.06) : "transparent" + Text { - text: entry.modelData.mod.label - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + id: entryIcon + anchors { left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter } + text: entry.modelData.mod.icon + font { family: Theme.iconFamily; pixelSize: Theme.fontSize } color: Theme.text } - // Which buried setting matched, when the label did not. - Text { - visible: entry.modelData.hit !== "" - width: parent.width - elide: Text.ElideRight - text: entry.modelData.hit - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 5 } - color: Theme.subtext + Column { + anchors { left: entryIcon.right; leftMargin: 10; right: parent.right; rightMargin: 8 + verticalCenter: parent.verticalCenter } + Text { + text: entry.modelData.mod.label + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + color: Theme.text + } + // Which buried setting matched, when the label did not. + Text { + visible: entry.modelData.hit !== "" + width: parent.width + elide: Text.ElideRight + text: entry.modelData.hit + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 5 } + color: Theme.subtext + } } - } - MouseArea { - id: area - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.go(entry.modelData) + MouseArea { + id: area + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: root.go(entry.modelData) + } } } } diff --git a/desktop/modules/appearance/IconsModule.qml b/desktop/modules/appearance/IconsModule.qml index f6559d1..bf3722b 100644 --- a/desktop/modules/appearance/IconsModule.qml +++ b/desktop/modules/appearance/IconsModule.qml @@ -19,6 +19,7 @@ Module { // nf-fa-mouse_pointer, present in Inconsolata Nerd Font. icon: "\uf245" settings: true + group: "Appearance" keywords: ["cursor", "pointer", "size", "gtk", "qt", "theme"] searchItems: Icons.iconThemes.map(n => ({ text: "icons: " + n, key: "icon:" + n })) .concat(Icons.cursorThemes.map(n => ({ text: "cursor: " + n, key: "cursor:" + n }))) diff --git a/desktop/modules/appearance/IdleModule.qml b/desktop/modules/appearance/IdleModule.qml index 231e192..4b27cd3 100644 --- a/desktop/modules/appearance/IdleModule.qml +++ b/desktop/modules/appearance/IdleModule.qml @@ -19,6 +19,7 @@ Module { // nf-fa-hourglass, present in Inconsolata Nerd Font. icon: "\uf254" settings: true + group: "Desktop" keywords: ["hypridle", "lock", "timeout", "screen", "dpms", "suspend", "sleep"] function refresh() { Hypridle.refresh(); } diff --git a/desktop/modules/appearance/SunsetModule.qml b/desktop/modules/appearance/SunsetModule.qml index 0f7fe79..557a2a4 100644 --- a/desktop/modules/appearance/SunsetModule.qml +++ b/desktop/modules/appearance/SunsetModule.qml @@ -19,6 +19,7 @@ Module { // nf-fa-moon_o, present in Inconsolata Nerd Font. icon: "\uf186" settings: true + group: "Desktop" keywords: ["hyprsunset", "night", "light", "temperature", "gamma", "location", "profile"] function refresh() { Hyprsunset.refresh(); } diff --git a/desktop/modules/appearance/ThemeModule.qml b/desktop/modules/appearance/ThemeModule.qml index 729ceb1..97ca519 100644 --- a/desktop/modules/appearance/ThemeModule.qml +++ b/desktop/modules/appearance/ThemeModule.qml @@ -19,6 +19,7 @@ Module { // nf-fa-paintbrush, present in Inconsolata Nerd Font. icon: "\uf1fc" settings: true + group: "Appearance" keywords: ["colour", "color", "scheme", "palette", "accent", "udt"] searchItems: Array.from(Udt.names).map(n => ({ text: n, key: n })) diff --git a/desktop/modules/appearance/WallpaperModule.qml b/desktop/modules/appearance/WallpaperModule.qml index 246e8f5..c21d94d 100644 --- a/desktop/modules/appearance/WallpaperModule.qml +++ b/desktop/modules/appearance/WallpaperModule.qml @@ -20,6 +20,7 @@ Module { // nf-fa-picture_o, present in Inconsolata Nerd Font. icon: "\uf03e" settings: true + group: "Appearance" keywords: ["background", "screen", "monitor", "wallp", "wallhaven", "horizontal", "vertical"] function refresh() { Wallpapers.refresh(); } diff --git a/desktop/modules/assistant/AssistantModule.qml b/desktop/modules/assistant/AssistantModule.qml index bd3e270..e89fe96 100644 --- a/desktop/modules/assistant/AssistantModule.qml +++ b/desktop/modules/assistant/AssistantModule.qml @@ -25,6 +25,7 @@ Module { // nf-fa-comments, present in Inconsolata Nerd Font. icon: "\uf086" settings: true + group: "Assistant" keywords: ["llm", "model", "llama", "server", "prompt", "temperature", "thinking", "rounds", "tools", "environment", "daemon", "restart"] diff --git a/desktop/modules/assistant/PresetsModule.qml b/desktop/modules/assistant/PresetsModule.qml index 9490bf7..8617b02 100644 --- a/desktop/modules/assistant/PresetsModule.qml +++ b/desktop/modules/assistant/PresetsModule.qml @@ -22,6 +22,7 @@ Module { // nf-fa-lightbulb_o, present in Inconsolata Nerd Font. icon: "" settings: true + group: "Assistant" keywords: ["assistant", "canvas", "ask", "question", "prompt", "summarize", "files"] searchItems: Presets.list(Prefs.presets).map((p, i) => ({ text: p.label + ": " + p.prompt, key: "preset:" + i })) diff --git a/desktop/modules/autostart/AutostartModule.qml b/desktop/modules/autostart/AutostartModule.qml index 24c69da..9bbe54b 100644 --- a/desktop/modules/autostart/AutostartModule.qml +++ b/desktop/modules/autostart/AutostartModule.qml @@ -24,6 +24,7 @@ Module { // nf-fa-rocket, present in Inconsolata Nerd Font. icon: "" settings: true + group: "Desktop" keywords: ["login", "startup", "launch", "exec", "daemon", "session", "workspace", "silent", "scratchpad", "autostart.lua", "hyprland"] diff --git a/desktop/modules/git/GitModule.qml b/desktop/modules/git/GitModule.qml index 6aa0bc6..bd0be71 100644 --- a/desktop/modules/git/GitModule.qml +++ b/desktop/modules/git/GitModule.qml @@ -23,6 +23,7 @@ Module { // nf-dev-git, present in Inconsolata Nerd Font. icon: "" settings: true + group: "Account" keywords: ["gitconfig"] // Every value, as the page lists it; key is the row's tag in GitPage. diff --git a/desktop/modules/user/UserModule.qml b/desktop/modules/user/UserModule.qml index 0d96050..79f1be5 100644 --- a/desktop/modules/user/UserModule.qml +++ b/desktop/modules/user/UserModule.qml @@ -21,6 +21,7 @@ Module { // nf-fa-user, present in Inconsolata Nerd Font. icon: "\uf007" settings: true + group: "Account" keywords: ["name", "email", "avatar", "picture", "photo", "language", "location", "signing", "key", "gpg", "accountsservice"] |
