diff options
Diffstat (limited to 'docs/superpowers/plans/2026-09-14-desktop-shell.md')
| -rw-r--r-- | docs/superpowers/plans/2026-09-14-desktop-shell.md | 125 |
1 files changed, 54 insertions, 71 deletions
diff --git a/docs/superpowers/plans/2026-09-14-desktop-shell.md b/docs/superpowers/plans/2026-09-14-desktop-shell.md index d263b2e..d067b15 100644 --- a/docs/superpowers/plans/2026-09-14-desktop-shell.md +++ b/docs/superpowers/plans/2026-09-14-desktop-shell.md @@ -71,7 +71,6 @@ desktop/ VmPage.qml VmPanel's content, rehomed appearance/ AppearanceModule.qml tile only, activate() calls the external shell - qmldir singleton registrations ``` Deleted when their contents have moved: `volume-osd/`, `mail-overview/`, @@ -80,11 +79,20 @@ Deleted when their contents have moved: `volume-osd/`, `mail-overview/`, ### A note on singletons `Player.qml`, `Accounts.qml`, `Virsh.qml` and `Theme.qml` are all -`pragma Singleton`. In the existing components they work because each is in the -component's root directory, which quickshell scans. Moving them into -`modules/<name>/` subdirectories means they are no longer in the root, so they -need a `qmldir` registering them. Task 1 creates it, and every later task that -moves a singleton adds its line. +`pragma Singleton`, and all three of the first group move into +`modules/<name>/` subdirectories. + +**They need no `qmldir`.** An earlier draft of this plan claimed a singleton +outside the config root is invisible until a `qmldir` names it. That was +wrong, and it was tested: a `pragma Singleton` in `modules/sub/`, reached by a +plain `import "modules/sub"`, resolves with no `qmldir` anywhere. The control +for that test was a reference to a genuinely undefined type, which produces a +visible `ReferenceError: <name> is not defined` warning; the singleton case +produced no such warning and the binding evaluated. + +So each module directory gets a plain directory import and nothing else. This +matches what AGENTS.md already says about `Theme.qml`: quickshell follows the +symlink and resolves the singleton with no qmldir and no consumer change. --- @@ -92,7 +100,6 @@ moves a singleton adds its line. **Files:** - Create: `desktop/shell.qml` -- Create: `desktop/qmldir` - Create: `desktop/Theme.qml` (symlink) - [ ] **Step 1: Create the directory and the Theme symlink** @@ -109,15 +116,7 @@ ls -l desktop/Theme.qml Expected: `desktop/Theme.qml -> ../shared/Theme.qml` -- [ ] **Step 2: Write the qmldir** - -`desktop/qmldir`: - -``` -singleton Theme 1.0 Theme.qml -``` - -- [ ] **Step 3: Write a shell that only holds itself open** +- [ ] **Step 2: Write a shell that only holds itself open** `desktop/shell.qml`: @@ -153,7 +152,7 @@ ShellRoot { } ``` -- [ ] **Step 4: Verify it loads and stays up** +- [ ] **Step 3: Verify it loads and stays up** Run it in the foreground under a timeout, so the harness owns the process: @@ -165,7 +164,7 @@ Expected: a line containing `Configuration Loaded`, no `QML` errors, and the command ending only when the timeout fires (exit 124). If it returns immediately with no error, the keepalive window is missing or malformed. -- [ ] **Step 5: Commit** +- [ ] **Step 4: Commit** ```bash git add desktop/ @@ -875,7 +874,6 @@ the page. - Create: `desktop/modules/sound/SoundPage.qml` - Move: `volume-osd/Player.qml` -> `desktop/modules/sound/Player.qml` - Move: `volume-osd/TransportButton.qml` -> `desktop/modules/sound/TransportButton.qml` -- Modify: `desktop/qmldir` - [ ] **Step 1: Move the two files that need no change** @@ -884,16 +882,10 @@ git mv volume-osd/Player.qml desktop/modules/sound/Player.qml git mv volume-osd/TransportButton.qml desktop/modules/sound/TransportButton.qml ``` -- [ ] **Step 2: Register Player as a singleton** - -`Player.qml` is `pragma Singleton` and is no longer in the config root, so it -needs a qmldir entry. Append to `desktop/qmldir`: +`Player.qml` is `pragma Singleton` and needs no registration: the directory +import in the shell resolves it. See "A note on singletons" above. -``` -singleton Player 1.0 modules/sound/Player.qml -``` - -- [ ] **Step 3: Write the service** +- [ ] **Step 2: Write the service** The PipeWire half of the old `VolumeOsd.qml`, with the two traps preserved verbatim in comment and code. @@ -978,7 +970,7 @@ Scope { } ``` -- [ ] **Step 4: Write the OSD** +- [ ] **Step 3: Write the OSD** The window half, keeping its namespace so the existing Hyprland blur rule needs no edit. The body is the old `VolumeOsd.qml` from its first `PanelWindow` @@ -1248,7 +1240,7 @@ document. When moving the file, take the glyph bytes from the original `volume-osd/VolumeOsd.qml` rather than retyping them, and check `git diff` shows no change to those literals. -- [ ] **Step 5: Write the tile content and the page** +- [ ] **Step 4: Write the tile content and the page** `desktop/modules/sound/SoundTile.qml`: @@ -1425,7 +1417,7 @@ Column { } ``` -- [ ] **Step 6: Write the module** +- [ ] **Step 5: Write the module** `desktop/modules/sound/SoundModule.qml`: @@ -1471,7 +1463,7 @@ Module { } ``` -- [ ] **Step 7: Register it and delete the old component** +- [ ] **Step 6: Register it and delete the old component** In `desktop/shell.qml`, add `import "modules/sound"` and put `SoundModule {}` first in the `modules` list, before `AppearanceModule {}`. @@ -1484,7 +1476,7 @@ git mv volume-osd/README.md desktop/modules/sound/README.md rmdir volume-osd ``` -- [ ] **Step 8: Verify the OSD still works and the page renders** +- [ ] **Step 7: Verify the OSD still works and the page renders** ```bash pkill -x qs @@ -1517,10 +1509,10 @@ qs -p window-switcher & Note these are detached and will not survive the tool call; they are for the user's session, so have the user start them, or leave them for the next login. -- [ ] **Step 9: Commit** +- [ ] **Step 8: Commit** ```bash -git add -A desktop/modules/sound volume-osd desktop/shell.qml desktop/qmldir +git add -A desktop/modules/sound volume-osd desktop/shell.qml git commit -m "feat(desktop): move volume-osd in as the sound module VolumeOsd.qml did three jobs in one file: PipeWire tracking, the OSD @@ -1544,7 +1536,6 @@ the page, and the three scripts move with it. - Create: `desktop/modules/mail/MailModule.qml` - Create: `desktop/modules/mail/MailTile.qml` - Create: `desktop/modules/mail/MailPage.qml` -- Modify: `desktop/qmldir` - [ ] **Step 1: Move the files that need no change** @@ -1559,15 +1550,10 @@ git mv mail-overview/waybar-mail.sh desktop/modules/mail/waybar-mail.sh git mv mail-overview/test-mail-notify.sh desktop/modules/mail/test-mail-notify.sh ``` -- [ ] **Step 2: Register Accounts as a singleton** +`Accounts.qml` is `pragma Singleton` and needs no registration: the directory +import in the shell resolves it. See "A note on singletons" above. -Append to `desktop/qmldir`: - -``` -singleton Accounts 1.0 modules/mail/Accounts.qml -``` - -- [ ] **Step 3: Check the scripts for self-referential paths** +- [ ] **Step 2: Check the scripts for self-referential paths** The scripts may locate siblings relative to their own directory. Check before assuming the move is transparent: @@ -1579,7 +1565,7 @@ grep -n 'dirname\|BASH_SOURCE\|\$0\|mail-overview' desktop/modules/mail/*.sh If any line hardcodes `mail-overview`, update it to the new path. If they use `$(dirname "$0")` they are already correct. -- [ ] **Step 4: Verify the test suite still passes** +- [ ] **Step 3: Verify the test suite still passes** This is the only automated oracle in the whole project. @@ -1590,7 +1576,7 @@ This is the only automated oracle in the whole project. Expected: `16 passed, 0 failed`. If the count differs, the move broke something; fix before continuing. -- [ ] **Step 5: Write the page** +- [ ] **Step 4: Write the page** `MailPanel.qml`'s content, with the window chrome dropped and `root.` reads pointing at the page. The heartbeat `FileView` moves in unchanged, including @@ -1820,7 +1806,7 @@ Column { } ``` -- [ ] **Step 6: Write the tile and the module** +- [ ] **Step 5: Write the tile and the module** `desktop/modules/mail/MailTile.qml`: @@ -1890,7 +1876,7 @@ Module { } ``` -- [ ] **Step 7: Register it and delete the old component** +- [ ] **Step 6: Register it and delete the old component** Add `import "modules/mail"` to `desktop/shell.qml` and put `MailModule {}` in the `modules` list, after sound. @@ -1901,7 +1887,7 @@ git mv mail-overview/README.md desktop/modules/mail/README.md rmdir mail-overview ``` -- [ ] **Step 8: Verify** +- [ ] **Step 7: Verify** ```bash pkill -x qs @@ -1920,7 +1906,7 @@ Expected: the test reporting `16 passed, 0 failed`, then `qs -p desktop ipc call drawer open mail` and confirm the account rows, thread previews and watcher dot all render as they did in the old drawer. -- [ ] **Step 9: Commit** +- [ ] **Step 8: Commit** ```bash git add -A desktop mail-overview @@ -1946,7 +1932,7 @@ The largest move. `Virsh.qml` becomes the module's service unchanged; - Create: `desktop/modules/vm/VmModule.qml` - Create: `desktop/modules/vm/VmTile.qml` - Create: `desktop/modules/vm/VmPage.qml` -- Modify: `desktop/qmldir`, `desktop/shell.qml` +- Modify: `desktop/shell.qml` - [ ] **Step 1: Move the two files that need no change** @@ -1964,15 +1950,10 @@ deleting: git show HEAD~1:vm-manager/Button.qml | diff - desktop/Button.qml && echo IDENTICAL ``` -- [ ] **Step 2: Register Virsh as a singleton** +`Virsh.qml` is `pragma Singleton` and needs no registration: the directory +import in the shell resolves it. See "A note on singletons" above. -Append to `desktop/qmldir`: - -``` -singleton Virsh 1.0 modules/vm/Virsh.qml -``` - -- [ ] **Step 3: Write the page** +- [ ] **Step 2: Write the page** `VmPanel.qml`'s content with the window chrome dropped. The confirm-step logic, the per-VM rows and the snapshot list all move unchanged; only the enclosing @@ -2346,7 +2327,7 @@ Column { Note the stat row changed from `Row` to `Flow`: four stats at 150px bars do not fit in a 600px drawer as one row, where they did in the old full-width panel. -- [ ] **Step 4: Write the tile and the module** +- [ ] **Step 3: Write the tile and the module** The tile shows one dot per VM. `Virsh` runs `virsh event --all --loop` unconditionally and refreshes the list on every lifecycle event, so @@ -2439,7 +2420,7 @@ Module { } ``` -- [ ] **Step 5: Keep the failure notification** +- [ ] **Step 4: Keep the failure notification** `vm-manager/shell.qml` turned `Virsh.actionFailed` into a `notify-send`. That belongs in the module now. Add to `VmModule.qml`, inside the `Module` block: @@ -2463,7 +2444,7 @@ belongs in the module now. Add to `VmModule.qml`, inside the `Module` block: and add `import Quickshell.Io` at the top of the file. -- [ ] **Step 6: Register it and delete the old component** +- [ ] **Step 5: Register it and delete the old component** Add `import "modules/vm"` to `desktop/shell.qml` and put `VmModule {}` in the `modules` list, after mail. @@ -2474,7 +2455,7 @@ git mv vm-manager/README.md desktop/modules/vm/README.md rmdir vm-manager ``` -- [ ] **Step 7: Verify** +- [ ] **Step 6: Verify** ```bash pkill -x qs @@ -2511,7 +2492,7 @@ file was edited when it should have been moved verbatim. A VM carrying a managed save shows "Discard saved state" among its actions; if the user has one, that button appearing is the end-to-end check. -- [ ] **Step 8: Commit** +- [ ] **Step 7: Commit** ```bash git add -A desktop vm-manager @@ -2627,10 +2608,11 @@ Two sections are now wrong: Add to the per-component notes, since both cost time to rediscover: ```markdown -- **A singleton outside the config root needs a `qmldir` entry.** The five - original components each kept their singletons beside `shell.qml`, where - quickshell finds them. Moving one into `modules/<name>/` makes it invisible - until `qmldir` names it. +- **A `pragma Singleton` in a subdirectory needs no `qmldir`.** A plain + directory import resolves it, the same way quickshell resolves the + `Theme.qml` symlink. Tested while merging the components: the control was a + reference to an undefined type, which warns `ReferenceError: <name> is not + defined`, and the singleton case produced no such warning. - **`Virsh.sampling` gates the 2s stats poll, not the whole service.** The lifecycle event stream runs unconditionally, which is what keeps the VM list and the tile's dots current while the page is closed. @@ -2654,9 +2636,10 @@ git add README.md AGENTS.md desktop/README.md git commit -m "docs: the desktop shell and what the merge changed Five components become three, and the Theme symlink count with them. Two -new notes: a singleton outside the config root is invisible without a -qmldir entry, and Virsh.sampling gates only the stats poll, not the -lifecycle stream that keeps the tile correct while the page is closed." +new notes: a pragma Singleton in a subdirectory resolves through a plain +directory import with no qmldir, and Virsh.sampling gates only the stats +poll, not the lifecycle stream that keeps the tile correct while the page +is closed." ``` --- |
