diff options
Diffstat (limited to 'docs/superpowers/plans')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md | 124 | ||||
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 92 |
2 files changed, 126 insertions, 90 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md index ef51b5c..783e4ed 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md @@ -6699,3 +6699,127 @@ database directly. **Verified:** clean build with no warnings from any changed file, 24 of 24 suites over three consecutive runs, 211 tests in `test_mainwindow`. Every one of the spec's six testing bullets has a test, each mutation-checked. + +## 115. A copy from the message pane gives no confirmation + +**Observed (user, 2026-08-17):** Copy link address, Copy image address and Copy +image all work, and none of them says so. The user asked for "a small +'link copied' transient that appears and disappears after a few seconds". + +**Cause:** not a defect, unbuilt. These are Chromium's own menu entries and it +does not report success; nothing in this application is listening to them. + +**Copy image was thought to be broken and is not**; see item 116 in the +closed-items file, which is worth reading for how a stale clipboard reading +produced a confident wrong cause. + +All three work. Copy image was briefly filed as broken (item 116) and is not: +the pixels reach the clipboard correctly, and the reading that said otherwise +was taken off a stale clipboard. So this item covers the confirmation for Copy +link address, Copy image address and Copy image alike. + +**Approach.** `MessageView::statusMessage` already exists and the status bar +already expires its messages (item 33), so this is one connection per action and +no new widget, no new timer. `QWebEnginePage::action()` gives each entry's +QAction; connect `triggered` and emit the appropriate string. + +**Constraints.** + +- The message must name what was copied. "Copied" alone is worse than nothing + when three entries sit next to each other in the same menu. +- Do not build a floating overlay for this. The status bar is where this + application reports transient results, and a second mechanism for the same + job is the kind of thing item 45 recorded when two Sync buttons disagreed. +- Depends on nothing; can be built alongside 114 since both touch the same menu. + +**Size: XS.** + +**Built 2026-08-19.** Four entries report through the pane's existing +`statusMessage`: Copy, Copy link address, Copy image and Copy image address, +each naming what it copied rather than saying "Copied". Connected to the PAGE's +own QActions in the constructor, which are the same instances the standard +context menu holds, so the report follows the entry wherever it is triggered +from and no menu of ours is involved. + +That is also what makes this fully testable, unlike item 117 beside it: +triggering the action runs the production path with no context-menu event +needed. The test enables each action first, since Chromium disables a copy entry +when there is nothing of that kind under the cursor and `trigger()` on a +disabled QAction emits nothing at all, which would have left the loop asserting +nothing while looking thorough. Two mutations fail it: a duplicated message, and +one entry left unwired. + +The strings are `QT_TR_NOOP` inside an array, which CLAUDE.md warns extracts +NOTHING at file scope. Verified rather than assumed: `lupdate` found all four +under the `MessageView` context with no warning, because the array sits inside +a member function where the class context exists. + +## 117. The message pane offers no Select all + +**Observed (user, 2026-08-17):** right-clicking a body selection offers Copy and +the search entries, and no Select all. Noticed while hand-testing item 100. + +**NOT caused by item 100, and this was verified rather than argued.** The user +ran a build with `src/messageview.cpp` and `src/messageview.h` reverted to HEAD, +so `removeBrowserActions()` did not exist, and reported the same menu: Copy and +the search entries only. Chromium's standard menu for this pane has never +carried Select all. + +**Three wrong theories preceded that measurement**, which is the part worth +recording, because each was plausible and each cost a round trip: + +1. *The separator sweep removed it.* Disproved with a standalone program + reproducing the sweep against a realistic menu: it drops the leading + separator and keeps every action. +2. *Chromium omits it when there is no selection.* Killed by the user, who had a + selection at the time. +3. *A probe will show what the real menu holds.* `createStandardContextMenu()` + returns NULL outside an actual context-menu event, on the offscreen platform + and on a real display alike, so two probe attempts measured nothing. + +The lesson is the one item 100 had already written down and the agent did not +follow: **a menu built by hand proves nothing about the menu Chromium builds.** +`theBodyMenuDropsTheBrowsersOwnActions` constructs its own QMenu, which is right +for testing the filter and useless for testing what is offered. That test now +says so, and deliberately does NOT assert on SelectAll, since a passing +assertion there would read as a guarantee the code does not make. + +**Approach.** Add it explicitly rather than hoping Chromium supplies it. The +action already exists as `QWebEnginePage::SelectAll` and works; only the menu +entry is missing. + +- `menu->addAction(page->action(QWebEnginePage::SelectAll))` in + `showBodyContextMenu`, placed beside Copy rather than appended after the + search entries. +- Worth considering a `Ctrl+A` binding for the pane at the same time, though + note the pane is not the only focusable widget and the query bar has its own + claim on that key. Check `KeyMap::defaultBindings()` before adding one. + +**Constraints.** + +- **A test for this cannot use a hand-built menu.** That is the trap above. The + honest options are asserting the action is in the menu the production code + returns, which needs a real context-menu event, or leaving it to a hand test + and saying so. Do not write a test that constructs a QMenu and calls it + covered. +- Select all selects the rendered body, not the header label, which is a + separate widget with its own selection. That is probably the desired + behaviour but should be looked at rather than assumed. + +**Size: XS.** + +**Built 2026-08-19** as `MessageView::addPaneActions()`, static and taking the +menu, mirroring `removeBrowserActions()` beside it. Two stale comments went with +it: both `showBodyContextMenu()` and the header of `removeBrowserActions()` +claimed Select all was among the entries the standard menu supplied and that the +filter preserved. Neither was true, and either would have sent the next reader +back down the same three wrong theories. + +**The call site is not covered, and the test says so rather than pretending.** +`addPaneActions()` has a test and a mutation dropping the entry fails it. A +mutation deleting the CALL from `showBodyContextMenu()` leaves the whole suite +green, measured, because `createStandardContextMenu()` returns nothing outside a +real context-menu event and the offscreen platform cannot deliver one. The +honest options the entry named were an assertion on the production menu or a +hand test; the first is impossible here, so it is the second, recorded in the +test so nobody adds an assertion that appears to cover it. diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md index 335b3d3..be52da9 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md @@ -179,9 +179,9 @@ taking that too literally. | 112 | Toggle unread on a whole thread cannot reach "all unread" on a partly-read thread | defect | S | open, found 2026-08-17. A toggle over a UNION has no direction on a mixed thread | | 113 | No way to see a message's HTML source | information | S | open, 2026-08-17. Chromium's own View source cannot work here; needs our own plain-text dialog. Item 100 removed the dead entry, which was an overreach: the user had not asked for it | | 114 | Save image is offered on every image and does nothing | defect | S | open, found 2026-08-17 by right-clicking a real image. No `downloadRequested` handler exists anywhere, so the request is emitted and never answered | -| 115 | A copy from the message pane gives no confirmation | presentation | XS | open, 2026-08-17. Copy link address, Copy image address and Copy image all work, silently. `statusMessage` already exists and already expires | +| 115 | A copy from the message pane gives no confirmation | presentation | XS | **done** 2026-08-19, unreleased. Four entries report, each naming what it copied; connected to the page's own QActions, so the entry is covered wherever it is triggered from | | 116 | Copy image copies markup instead of the image | defect | XS | **dropped** 2026-08-17, same day. NOT A DEFECT: `wl-paste --list-types` run immediately after a copy reports `image/png`, `application/x-qt-image` and 30 more image flavours. The clipboard is correct and Chromium is behaving. The earlier "text only" reading was taken minutes late off a clipboard that had been overwritten, and a whole cause was theorised on it | -| 117 | The message pane offers no Select all | workflow | XS | open, found 2026-08-17. NOT caused by item 100: verified by hand against a build with that filter reverted, and the menu holds Copy and the search entries either way | +| 117 | The message pane offers no Select all | workflow | XS | **done** 2026-08-19, unreleased. `addPaneActions()` supplies it. The call site is NOT covered by a test and cannot be: the production menu needs a real context-menu event. Stated in the test rather than faked | | 118 | No way to empty the trash from inside the app | workflow | S | open, 2026-08-17. **Blocked on 103**, which creates the trash in the first place. Deliberately left out of 103's spec at the user's request rather than squeezed in | | 119 | The unsynced-changes count cannot be opened to see what it counts | information | S | open, 2026-08-19, from the notes. One of the four things it sums carries no message ids at all, so a list cannot be complete without a change to how the count is kept | @@ -717,94 +717,6 @@ for the network to satisfy it. **Size: S.** -## 115. A copy from the message pane gives no confirmation - -**Observed (user, 2026-08-17):** Copy link address, Copy image address and Copy -image all work, and none of them says so. The user asked for "a small -'link copied' transient that appears and disappears after a few seconds". - -**Cause:** not a defect, unbuilt. These are Chromium's own menu entries and it -does not report success; nothing in this application is listening to them. - -**Copy image was thought to be broken and is not**; see item 116 in the -closed-items file, which is worth reading for how a stale clipboard reading -produced a confident wrong cause. - -All three work. Copy image was briefly filed as broken (item 116) and is not: -the pixels reach the clipboard correctly, and the reading that said otherwise -was taken off a stale clipboard. So this item covers the confirmation for Copy -link address, Copy image address and Copy image alike. - -**Approach.** `MessageView::statusMessage` already exists and the status bar -already expires its messages (item 33), so this is one connection per action and -no new widget, no new timer. `QWebEnginePage::action()` gives each entry's -QAction; connect `triggered` and emit the appropriate string. - -**Constraints.** - -- The message must name what was copied. "Copied" alone is worse than nothing - when three entries sit next to each other in the same menu. -- Do not build a floating overlay for this. The status bar is where this - application reports transient results, and a second mechanism for the same - job is the kind of thing item 45 recorded when two Sync buttons disagreed. -- Depends on nothing; can be built alongside 114 since both touch the same menu. - -**Size: XS.** - -## 117. The message pane offers no Select all - -**Observed (user, 2026-08-17):** right-clicking a body selection offers Copy and -the search entries, and no Select all. Noticed while hand-testing item 100. - -**NOT caused by item 100, and this was verified rather than argued.** The user -ran a build with `src/messageview.cpp` and `src/messageview.h` reverted to HEAD, -so `removeBrowserActions()` did not exist, and reported the same menu: Copy and -the search entries only. Chromium's standard menu for this pane has never -carried Select all. - -**Three wrong theories preceded that measurement**, which is the part worth -recording, because each was plausible and each cost a round trip: - -1. *The separator sweep removed it.* Disproved with a standalone program - reproducing the sweep against a realistic menu: it drops the leading - separator and keeps every action. -2. *Chromium omits it when there is no selection.* Killed by the user, who had a - selection at the time. -3. *A probe will show what the real menu holds.* `createStandardContextMenu()` - returns NULL outside an actual context-menu event, on the offscreen platform - and on a real display alike, so two probe attempts measured nothing. - -The lesson is the one item 100 had already written down and the agent did not -follow: **a menu built by hand proves nothing about the menu Chromium builds.** -`theBodyMenuDropsTheBrowsersOwnActions` constructs its own QMenu, which is right -for testing the filter and useless for testing what is offered. That test now -says so, and deliberately does NOT assert on SelectAll, since a passing -assertion there would read as a guarantee the code does not make. - -**Approach.** Add it explicitly rather than hoping Chromium supplies it. The -action already exists as `QWebEnginePage::SelectAll` and works; only the menu -entry is missing. - -- `menu->addAction(page->action(QWebEnginePage::SelectAll))` in - `showBodyContextMenu`, placed beside Copy rather than appended after the - search entries. -- Worth considering a `Ctrl+A` binding for the pane at the same time, though - note the pane is not the only focusable widget and the query bar has its own - claim on that key. Check `KeyMap::defaultBindings()` before adding one. - -**Constraints.** - -- **A test for this cannot use a hand-built menu.** That is the trap above. The - honest options are asserting the action is in the menu the production code - returns, which needs a real context-menu event, or leaving it to a hand test - and saying so. Do not write a test that constructs a QMenu and calls it - covered. -- Select all selects the rendered body, not the header label, which is a - separate widget with its own selection. That is probably the desired - behaviour but should be looked at rather than assumed. - -**Size: XS.** - ## 118. No way to empty the trash from inside the app **Observed (user, 2026-08-17):** raised while reviewing item 103's spec, as |
