From 1c68c391cd10b5726d082d487b97e7decb823512 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 17 Oct 2026 10:06:12 +0200 Subject: desktop: settings search finds rows, and a hit reveals its row Search used to stop at the page: clicking a result opened it at the top and left the setting to be found by eye. Now each settings module keeps its rows as searchItems, {text, key}, reread on every window open since the page itself is not loaded until shown: git runs gitcfg list, and autostart watches its file. A row hit opens the page, and Page.reveal() finds the row whose objectName is the key, waiting up to 3s for the page's own data, scrolls to it and flashes it in the accent. The reveal lives in Page, so a page only names its rows. Git's long keyword list was a stand-in for exactly this and is cut to "gitconfig". The autostart page takes its path from the module now that both read the file. Also corrects the AGENTS note on missed hot reloads: it blamed sed -i replacing the file, but the Edit tool writes a new inode too and usually reloads. The cause is unknown; the note now says how to detect it and that a process that stops watching needs a restart. Co-Authored-By: Claude Opus 5.5 --- desktop/modules/autostart/AutostartModule.qml | 21 +++++++++++++++++++-- desktop/modules/autostart/AutostartPage.qml | 7 +++++-- desktop/modules/git/GitModule.qml | 18 +++++++++++++----- desktop/modules/git/GitPage.qml | 2 ++ 4 files changed, 39 insertions(+), 9 deletions(-) (limited to 'desktop/modules') diff --git a/desktop/modules/autostart/AutostartModule.qml b/desktop/modules/autostart/AutostartModule.qml index ef4c005..24c69da 100644 --- a/desktop/modules/autostart/AutostartModule.qml +++ b/desktop/modules/autostart/AutostartModule.qml @@ -9,24 +9,41 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +import Quickshell +import Quickshell.Io import QtQuick import "../.." +import "Autostart.js" as A // What Hyprland launches at login, from hypr-theme's autostart.lua. Set once // and left alone, so it lives in the settings window, not on a tile. Module { + id: am name: "autostart" label: "Autostart" // nf-fa-rocket, present in Inconsolata Nerd Font. - icon: "\uf135" + icon: "" settings: true keywords: ["login", "startup", "launch", "exec", "daemon", "session", "workspace", "silent", "scratchpad", "autostart.lua", "hyprland"] + readonly property string file: (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + + "/hypr/sections/autostart.lua" + + // Every entry, as the page lists it; key is the row's objectName there. + function refresh() { fv.reload(); } + property FileView fv: FileView { + path: am.file + printErrors: false + watchChanges: true + onFileChanged: reload() + onLoaded: am.searchItems = A.parse(text()).map(e => ({ text: e.cmd, key: e.cmd })) + } + page: Component { Page { title: "Autostart" - AutostartPage { width: parent.width } + AutostartPage { width: parent.width; file: am.file } } } } diff --git a/desktop/modules/autostart/AutostartPage.qml b/desktop/modules/autostart/AutostartPage.qml index 1289a93..e0fa2c9 100644 --- a/desktop/modules/autostart/AutostartPage.qml +++ b/desktop/modules/autostart/AutostartPage.qml @@ -29,6 +29,8 @@ Column { spacing: 6 readonly property string home: Quickshell.env("HOME") + // autostart.lua, from the module. + required property string file property var entries: [] // Entry index -> the program's resolved path, "" when it is not found. property var found: ({}) @@ -48,8 +50,7 @@ Column { FileView { id: fv - path: (Quickshell.env("XDG_CONFIG_HOME") || page.home + "/.config") - + "/hypr/sections/autostart.lua" + path: page.file // Hyprland reloads its config on every change, so a half-written file // would reach it. atomicWrites: true @@ -253,6 +254,8 @@ Column { readonly property var parts: A.split(modelData.cmd) readonly property var where: A.workspace(parts.rule) readonly property string path: page.found[modelData.index] ?? "?" + // What a search hit scrolls to (AutostartModule's searchItems key). + objectName: modelData.cmd width: page.width height: 44 diff --git a/desktop/modules/git/GitModule.qml b/desktop/modules/git/GitModule.qml index aaa72a9..6aa0bc6 100644 --- a/desktop/modules/git/GitModule.qml +++ b/desktop/modules/git/GitModule.qml @@ -9,8 +9,10 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +import Quickshell.Io import QtQuick import "../.." +import "Git.js" as G // The global git config, in the settings window: set once and left alone. // The user page's "More git settings" opens it there. @@ -21,11 +23,17 @@ Module { // nf-dev-git, present in Inconsolata Nerd Font. icon: "" settings: true - keywords: ["gitconfig", "user", "name", "email", "signingkey", "signing", "gpg", - "alias", "core", "editor", "pager", "commit", "gpgsign", "init", - "defaultBranch", "branch", "pull", "push", "fetch", "rebase", "merge", - "diff", "log", "color", "credential", "lfs", "rerere", "tag", "status", - "safe", "directory"] + keywords: ["gitconfig"] + + // Every value, as the page lists it; key is the row's tag in GitPage. + function refresh() { proc.running = false; proc.running = true; } + property Process proc: Process { + command: [Qt.resolvedUrl("gitcfg").toString().replace(/^file:\/\//, ""), "list"] + stdout: StdioCollector { + onStreamFinished: gm.searchItems = text.startsWith("error=") ? [] + : G.parse(text).map(e => ({ text: e.name + " = " + e.value, key: e.name + "=" + e.value })) + } + } page: Component { Page { diff --git a/desktop/modules/git/GitPage.qml b/desktop/modules/git/GitPage.qml index 6edf085..c5d04d9 100644 --- a/desktop/modules/git/GitPage.qml +++ b/desktop/modules/git/GitPage.qml @@ -244,6 +244,8 @@ Column { // An Item with anchors, not a Row: a Row sizes to its children // and fixed widths in one overflow the page (AGENTS.md). Item { + // What a search hit scrolls to (GitModule's searchItems key). + objectName: row.tag width: parent.width height: 34 -- cgit v1.2.3