Finish the wonderland: System told truthfully, in eight tabs instead of ten
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -7,12 +7,12 @@
|
||||
// So the manual is prose, in chapters, rendered here rather than opened in a
|
||||
// browser. Keeping it in Settings means it is reachable from the same place
|
||||
// as everything else it talks about, and a link to a settings page can just
|
||||
// be a settings page.
|
||||
// be a settings page -- see onLinkActivated below, where that stopped being a
|
||||
// figure of speech.
|
||||
//
|
||||
// The chapters live beside the shell in manual/, not at the repository root.
|
||||
// They are read at runtime through Quickshell.shellDir, which resolves whether
|
||||
// or not the repository is where it usually is; a path walked upward out of
|
||||
// the shell directory does not.
|
||||
// The chapter list and the chapter titles both come from ManualChapters, which
|
||||
// reads each file's own first heading. This page used to carry a hand-written
|
||||
// copy of those titles under a comment claiming they were read from the files.
|
||||
//
|
||||
// One Text per chapter, never the whole manual at once: Text has an implicit
|
||||
// texture size limit, and a document long enough to hit it fails by going
|
||||
@@ -30,16 +30,7 @@ SettingsPage {
|
||||
title: "Manual"
|
||||
lede: "How this desktop works, for the person using it."
|
||||
|
||||
// Chapter files are numbered so their order is their filename. The title
|
||||
// shown here is the first heading of each, read from the file, so a
|
||||
// chapter cannot be renamed in one place and not the other.
|
||||
readonly property var chapters: [
|
||||
{ file: "01-coming-from-another-desktop.md", label: "Coming from another desktop" },
|
||||
{ file: "02-the-keyboard.md", label: "The keyboard" },
|
||||
{ file: "03-windows-and-workspaces.md", label: "Windows and workspaces" },
|
||||
{ file: "04-when-something-breaks.md", label: "When something breaks" },
|
||||
{ file: "05-making-it-yours.md", label: "Making it yours" }
|
||||
]
|
||||
readonly property var chapters: contents.titled
|
||||
|
||||
property int current: 0
|
||||
|
||||
@@ -56,10 +47,12 @@ SettingsPage {
|
||||
}
|
||||
}
|
||||
|
||||
ManualChapters { id: contents }
|
||||
|
||||
SettingsTabs {
|
||||
tabs: root.chapters.map((chapter, index) => ({
|
||||
value: String(index),
|
||||
label: chapter.label
|
||||
label: chapter.title
|
||||
}))
|
||||
current: String(root.current)
|
||||
onSelected: value => root.current = parseInt(value, 10)
|
||||
@@ -90,7 +83,30 @@ SettingsPage {
|
||||
// size; a document read once needs to be easy on the first pass.
|
||||
lineHeight: 1.35
|
||||
|
||||
onLinkActivated: link => Qt.openUrlExternally(link)
|
||||
// A link that names a settings page opens that page instead of a
|
||||
// browser, which is the whole reason the manual lives inside
|
||||
// Settings. Anything else -- a project URL, a wiki -- still leaves
|
||||
// the desktop.
|
||||
//
|
||||
// The scheme is Panama's own, so a chapter can never accidentally
|
||||
// hand an http link to openSettings, and an unknown page cannot be
|
||||
// smuggled in either: SettingsRoutes.resolve turns anything it does
|
||||
// not recognise into Home rather than a blank loader. A fragment,
|
||||
// where there is one, is the section within the page.
|
||||
onLinkActivated: link => {
|
||||
const target = String(link ?? "");
|
||||
const scheme = "panama://settings/";
|
||||
if (target.indexOf(scheme) !== 0) {
|
||||
Qt.openUrlExternally(target);
|
||||
return;
|
||||
}
|
||||
const rest = target.slice(scheme.length);
|
||||
const hash = rest.indexOf("#");
|
||||
if (hash < 0)
|
||||
ShellState.openSettings(rest);
|
||||
else
|
||||
ShellState.openSettingsSection(rest.slice(0, hash), rest.slice(hash + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user