diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-04 11:26:41 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-04 12:54:50 +0200 |
| commit | 1fda7abc56df02c9a255fe0863244c0364562f7d (patch) | |
| tree | 9f48ba5e921e63bd4aea54f8cf6945e8d9437038 /docs/superpowers/plans | |
| parent | 3b0a52b8620d3cead2f527d108ba64bfec8ee273 (diff) | |
| download | qtmaildir-1fda7abc56df02c9a255fe0863244c0364562f7d.tar.gz qtmaildir-1fda7abc56df02c9a255fe0863244c0364562f7d.zip | |
docs: add items 24 and 25 from the user's notes
Right-click actions on the thread list, and select-all for bulk tagging.
Item 24 records that there is no context menu anywhere in the
application: no contextMenuEvent override and no CustomContextMenu policy
in src/. The actions themselves already exist as QActions, so the work is
presentation, with one trap worth naming: right-clicking does not change
the selection in Qt, so a menu built naively would act on the row under
the cursor while the user is looking at several selected rows.
Item 25 is smaller than it sounds, and the entry says why. The thread
view is already ExtendedSelection and tagSelected() already acts on every
selected row through one combined query, so Ctrl+click bulk tagging works
today. What is missing is a select_all action, which does not exist for
the list, and any indication that multi-select is possible at all. It
also carries a caution: select-all over a 10k-thread query turns a rare
accident into a routine keystroke, and the combined-query design should
be measured against a real query before the binding ships rather than
assumed to scale.
Both are the user's own observations; the plan did not carry either.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs/superpowers/plans')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 60 |
1 files changed, 60 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 8f19d6b..205710a 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 @@ -62,6 +62,8 @@ taking that too literally. | 21 | Default shortcuts are not sensible enough | discoverability | S | open | | 22 | Translatability audit and i18n wiring | correctness | M | open | | 23 | No way to save a search query from the UI | workflow | M | open | +| 24 | No right-click actions on the thread list | discoverability | S | open | +| 25 | No select-all, and bulk actions are undiscoverable | workflow | S | open | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -1057,6 +1059,64 @@ exactly this: "saved queries that carry their own account scope, so one action gets there". If saved queries gain an account scope here, item 10 may be answered as a side effect rather than needing its own work. +## 24. No right-click actions on the thread list + +**Observed (user, 2026-08-04):** "right click actions on the list (left pane)". + +**Cause: there is no context menu anywhere in the application.** No +`contextMenuEvent` override and no `Qt::CustomContextMenu` policy in `src/`; +grep finds neither. Right-clicking a thread does nothing at all. + +**Approach.** The actions already exist as `QAction`s from item 3, so this is +presentation rather than new behaviour: set `Qt::CustomContextMenu` on the +thread view and build the menu from `m_actions`, exactly as `buildMenus()` +already does. Nothing should be reachable from the context menu that is not +reachable from the menu bar, or the two drift. + +**Constraints.** + +- **Show the shortcut in the menu**, which a `QAction` does for free. The + context menu is where a mouse user discovers the key for next time, and this + backlog exists because the app did not teach its own bindings. +- The menu must act on the **selection**, not on the row under the cursor, or + right-clicking inside a multi-row selection would silently act on one thread. + Qt does not do this for you: right-clicking does not change the selection, so + the row under the cursor and the selected rows can differ. +- Include the destructive entries (archive, delete, spam) without a + confirmation dialog, per `CLAUDE.md`. Undo covers them. + +## 25. No select-all, and bulk actions are undiscoverable + +**Observed (user, 2026-08-04):** "bulk select/select all for defined actions? +tags, read/unread, archive, delete". + +**Cause: half of this already works, and nothing says so.** The thread view is +already `QAbstractItemView::ExtendedSelection` (`src/mainwindow.cpp:408`), and +`tagSelected()` already acts on every `selectedRows()` entry, resolving them in +ONE combined query per `CLAUDE.md`. Ctrl+click and Shift+click therefore do +bulk tagging today. + +What is genuinely missing is smaller than the item sounds: + +- **No select-all action.** `selectAll` appears once in `src/`, on the query + bar, not the thread list. There is no `Ctrl+A` for the list and no menu entry. +- **No indication that multi-select exists.** With no context menu (item 24) and + no selection count anywhere, a user has no reason to think Ctrl+click will do + anything useful. + +**Approach.** Add a `select_all` action bound to `Ctrl+A`, scoped to the thread +list rather than the window, so it does not steal Ctrl+A from the query bar. +Then surface the selection size: the status bar already reports "%1: %n +thread(s)" after a tag action, and saying how many rows are selected before one +is the same idea a moment earlier. + +**Constraint: verify what a large selection costs before encouraging one.** +Select-all over a 10k-thread query makes `tagSelected()` build a 10k-id list and +`applyTagsToThreads()` one enormous `thread:a or thread:b or ...` query. The +combined-query design is what makes this plausible at all, but "plausible" is +not "measured", and this item is the one that turns a rare accident into a +routine keystroke. Measure it against a real query before shipping the binding. + --- ## Deferred, unsized, or split out |
