diff options
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 112 |
1 files changed, 112 insertions, 0 deletions
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 5d175a5..33d6a61 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 @@ -113,6 +113,8 @@ taking that too literally. | 53 | Message rows still read as a table, not as a conversation | presentation | ? | open, unspecified | | 54 | A cron sync carries the edits but the count still says pending | correctness | S | **done** | | 55 | In a narrow window the message pane is invisible | presentation | XS | open | +| 56 | No action carries an icon, so the toolbar reserves space for nothing | presentation | S | open | +| 57 | "Flag" would read better as "Important" or "Starred" | presentation | XS | open | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -3387,6 +3389,116 @@ must go behind the same "no saved state" check as the geometry. geometry is saved; the reported case is a user-sized window, so widening the default fixes nothing. +## 56. No action carries an icon, so the toolbar reserves space for nothing + +**Observed (user, 2026-08-09):** "icons inconsistency. All buttons should have +them, at least in the main window interface. Better if also the popups have +them." And: "Buttons should honor the 'Icon only' option." + +**Cause, verified in code.** The mechanism exists and is used; it simply does not +cover most actions. `src/mainwindow.cpp:902-919` holds a `themeIcons` table +mapping action names to freedesktop icon names and calls `setIcon()` for each, +guarded so a name the theme lacks leaves the action with text alone. It covers +**eight** actions: `sync`, `archive`, `delete`, `undo`, `spam`, `flag`, `quit`, +`focus_query`. + +Everything else registered through `MainWindow::addAction()` +(`src/mainwindow.cpp:598`) gets none, and there are roughly twenty of them: +`toggle_unread`, `mark_all_read`, `edit_tags`, `select_all`, `clear_pane`, +`clear_selection`, `zoom_in`, `zoom_out`, `zoom_reset`, `toggle_html`, +`load_remote`, `message_details`, `complete_query`, `next_thread`, +`prev_thread`, `open_thread`. That is the reported inconsistency: adjacent +entries in one menu, some with an icon and some without, which reads worse than +none having one. + +The toolbar is `setToolButtonStyle(Qt::ToolButtonTextBesideIcon)` +(`src/mainwindow.cpp:948`), so an action without an icon lays out an empty slot +beside its text. + +**The names are not the obstacle.** Probed against this desktop's theme +(`Material-Black-Plum-Suru`) with a throwaway Qt program: the eight in use all +resolve, and so do `mail-mark-unread`, `view-refresh`, `edit-select-all`, +`zoom-in`, `zoom-out`, `zoom-original`, `tag`, `mail-message-new`, `edit-clear` +and `help-about`. So the missing icons are missing because no name was assigned, +not because the theme lacks art. On another desktop the guard already handles a +name that does not resolve. + +**The "Icon only" half is separate, and is a genuine override.** Qt takes the +desktop's toolbar button style from the platform theme, and the hardcoded +`setToolButtonStyle()` at line 948 **overrides** the user's choice, so an "Icon +only" setting cannot take effect. Honouring it means dropping that call, or +reading `QApplication::style()->styleHint(QStyle::SH_ToolButtonStyle)` instead of +asserting a style. This is the smaller of the two halves and is independent of +the first. + +**Dialogs are a third case.** `QDialogButtonBox` standard buttons take their +icons from the platform style, so whether Ok and Cancel carry one is a style +question rather than something this code decides. + +**Approach.** Extend the existing `themeIcons` table to the remaining actions, +and stop overriding the toolbar button style. No new mechanism is needed; the +table and its null guard already do the work. + +**Constraints.** + +- Keep the null-icon guard. It is what makes a theme without a given name + degrade to text rather than to an empty slot. +- Prefer theme names over shipped art. Per-action bitmaps in `src/resources.qrc` + would grow the package for something the desktop already provides; that file + currently carries only the application icon and two subsetted fonts. +- Item 3 (done) added the buttons and menu entries. This is decoration on top of + that: no action should be added, removed or rebound here. +- `flag` already maps to `mail-mark-important`, which agrees with item 57's + proposed rename. Do the two together if 57 is picked up. + +**Verification.** `test_mainwindow` can assert that every action in `m_actions` +has a non-null icon. Note what that test does and does not prove: it passes only +on a machine whose icon theme resolves the names, so it is an assertion about +this desktop as much as about the code, and it says nothing about whether the +icon chosen is the *right* one. + +## 57. "Flag" would read better as "Important" or "Starred" + +**Observed (user, 2026-08-09):** "Flagged to be renamed as 'Important' or +'Starred', with a ⭐ as icon." + +**Cause.** Naming, not a defect. The action is created as `tr("&Flag")` at +`src/mainwindow.cpp:684` and applies the tag through +`tagSelected({ QStringLiteral("flagged") }, {}, tr("Flag"))` at +`src/mainwindow.cpp:686`, the second `tr("Flag")` being the undo-stack +description the user sees in the Undo entry. + +**The rename must not reach the tag.** `flagged` is a notmuch tag, and notmuch +tags are wire format: `src/types.h:37` tests for it, `src/tagcolors.cpp:31` +colours it, `src/threadlistmodel.cpp:145` lists it among the tags a row shows +another way, and the user's own `neomutt` and saved queries refer to it. Renaming +the tag would rewrite the mail store and desynchronise every other tool. Only the +**label** changes: the action text, the undo description, and any prose that says +"flag". + +**The star already exists.** `ThreadListModel::flagGlyph()` +(`src/threadlistmodel.cpp:62`) returns a solid star, with a `*` fallback when the +system font cannot draw it, and the flag column already paints it +(`src/threadlistmodel.cpp:213`). So the icon half of the note is shipped for the +list; what is missing is an icon on the *action*, which is item 56's business. + +**Approach.** Pick one of "Important" or "Starred" and change the action text, +the undo description, and the keyboard-shortcut reference entry. Ask the user +which word: they offered two and the choice is theirs, and it should agree with +whatever the icon depicts (a star suggests "Starred"). + +**Constraints.** + +- Every changed string is inside `tr()` and must stay there. +- The accelerator `&F` is taken from "Flag" and a new word needs a new one. The + Message menu currently holds `&Archive`, `&Delete`, `Mark &spam`, `Toggle + &unread`, `Mark all &read`, `Edit &tags`, `&Flag` + (`src/mainwindow.cpp:864-871`), so **"Important" can take `&I` freely, while + "Starred" collides with `Mark &spam` on `&S`** and would need a letter from + inside the word. A small argument for "Important". +- `src/tagdialog.cpp:211` mentions `flagged` in a comment about token completion. + That is the tag, not a label, and must not be touched. + ## Deferred, unsized, or split out Items noted while triaging but not part of the original list. Same numbering |
