From fdbe1d207e2fbdf3224c929ff24e947fe8591ba3 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 15 Aug 2026 10:21:08 +0200 Subject: docs: spec built-in filters as item 93, fold item 90 into it Explaining item 90 to the user produced a reframing rather than a fix. The buttons and the "more queries" menu are two different kinds of thing sharing one mechanism: a filter narrows whatever the user is looking at and should compose with the account dropdown, while a saved query is a self-contained destination entitled to set the account itself. Nothing ships as a default today, so the buttons are whatever the user pinned, which the queries.json migration did to every [queries] entry. That drift is the defect. Item 93 ships four built-in filters, Unread, Inbox, Flagged and Sent, as generated entries in the closed kQueryGenerators set that already exists for Sent. The user's own pinned queries are unpinned rather than deleted once the buttons are confirmed working. Three findings from reading the code, all in the spec. A generator must answer per account rather than having its all-accounts query wrapped in a scope, or Sent becomes path:"a/**" and (path:"a/Sent/**" or path:"b/Sent/**"), which returns the right rows only because path: is hierarchical. Sent is flat and the other three are not, so the four match in scope and not in view mode. And m_accountBox has no signal connected to it, which is now a decision rather than an omission: changing the account runs nothing, the button is the verb. Item 90's section moves to the closed file, kept in full because its cause and the rules preview that motivated the reset are still true of the code. --- .../plans/2026-08-03-post-0.1.0-usability.md | 90 ++++++++++------------ 1 file changed, 39 insertions(+), 51 deletions(-) (limited to 'docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md') 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 841ee91..9b38d03 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 @@ -154,9 +154,10 @@ taking that too literally. | 85 | Nothing on screen can be searched for by right-clicking it | workflow | M | **done** 2026-08-14, unreleased; see `specs/2026-08-14-search-from-message-design.md`. Split from 78; rebuilt the details dialog as rows | | 86 | A right-click search can replace or narrow, but never exclude | workflow | S | **done** 2026-08-14, unreleased; see `specs/2026-08-14-exclude-from-search-design.md`. Follows 85. The `extend` bool became a `SearchMode` enum across four signatures | | 89 | A sync moves the list under the user's hands, and the auto-sync skips rather than retries | workflow | M | open; from the 2026-08-15 notes pass. Two faults under one complaint, and the larger half is a design question | -| 90 | A saved-query button clears the account selection | workflow | S | open; from the 2026-08-15 notes pass. Cause is a DELIBERATE line; decision needed from the user before any change | +| 90 | A saved-query button clears the account selection | workflow | S | **folded into 93** 2026-08-15. Not fixed in place: the button that misbehaves stops being a saved query at all. See `specs/2026-08-15-builtin-filters-design.md` | | 91 | Double-clicking a thread could open it in its own window | workflow | ? | open, unspecified; the user marked it "(?) UX not sure" | | 92 | Nothing distinguishes a tag written by a rule from one the user applied | information | ? | open, unspecified; the user asked it as a question, and the answer decides whether it is a display item or a format change across two repos | +| 93 | The query buttons are whatever the user pinned, not a designed set of filters | workflow | M | open, specified 2026-08-15; see `specs/2026-08-15-builtin-filters-design.md`. Absorbs item 90. Four built-in filters that compose with the account dropdown | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -545,56 +546,43 @@ work. - Do not restore the pre-0.16.0 behaviour by making the delay negative for the user. `auto_sync_delay_ms` is theirs to set. -## 90. A saved-query button clears the account selection - -**Observed (user, notes):** "select an account and hit the 'unread' button, the -panel should show unread messages from that account only, instead it refreshes -the 'all accounts' list." - -**Cause, and it is a deliberate line, not an oversight.** -`MainWindow::runSavedQuery()` (`src/mainwindow.cpp:1907`) resets the account box -whenever the saved query names no account: - -```cpp -const int index = saved.account.isEmpty() - ? m_accountBox->findData(QString()) - : m_accountBox->findData(saved.account); -if (index >= 0) - m_accountBox->setCurrentIndex(index); -``` - -The comment above it states the intent: "An unscoped query CLEARS the selection -rather than inheriting whatever was there, which is the defect the rules preview -hit." `runQuery()` (`:2020`) then scopes whatever the box holds, so with the -reset removed the button would inherit the selection and the user would get what -they asked for. - -**So this is a decision, not a bug to fix quietly.** Two behaviours are -defensible and each breaks the other's case: - -- **Inherit.** The account box is a persistent scope and the buttons are - queries within it. This is what the note asks for. The risk is the one the - comment names: a query that already scopes itself, such as a rules preview - with `path:"work/**"`, gets scoped twice and matches nothing. -- **Reset.** A saved query is self-contained and says exactly what it shows. - This is what ships. Its cost is that the account dropdown looks like a filter - and silently is not. - -**Approach.** Ask the user which they want before writing anything. If it is -inherit, the narrow version is to inherit only for hand-written and generated -entries and keep the reset for a preview, since a preview is the one caller that -supplies its own path; the rules preview already forces index 0 itself at -`:1637`, so it does not depend on this line. - -**Constraints.** - -- Whatever is chosen, one rule for every saved-query surface: the buttons, the - menu and the dropdown all reach `runSavedQuery()`, and three behaviours here - would be worse than either one. -- A saved query that DOES name an account must keep overriding the box. That is - not in question and no test should lose it. -- `Account::scopedQuery()` is the only place a scope is applied. Do not add a - second one to make a caller behave. +## 93. The query buttons are whatever the user pinned, not a designed set of filters + +**Observed (user, 2026-08-15),** reached by explaining item 90 rather than from +the notes: + +> The queries that show as buttons shouldn't be in the same league as the ones I +> write and store in the "more queries" menu. If I see "Unread" as a button, I +> read it as "filter all my mails and show me only what is not yet read", but +> being a button, in my head it should cooperate with other UI elements. So if a +> dropdown offers to select an account, that same button should work with that +> selection transparently, not fight it. + +**Cause.** Nothing ships as a default. `Config::startupSavedQuery()` falls back +to `m_savedQueries.first()` and a fresh install has an empty query row, so every +button the user has is one they wrote into `[queries]` and that the queries.json +migration pinned (`src/config.cpp:455`). The buttons became "whatever is pinned" +by migration, never by design. The user's own words: "that's the direction I +wanted from the start, we drifted to what is today". + +**Approach.** Four built-in filters, Unread, Inbox, Flagged and Sent, as +generated entries in the closed set `kQueryGenerators` that already exists for +Sent. They compose with the account dropdown; saved queries keep setting the +account from what they stored. The user's own pinned queries are UNPINNED once +the buttons are confirmed working, never deleted, so they fold into the menu and +stay recoverable. + +**Absorbs item 90.** The button that clears the account selection stops being a +saved query at all, so there is nothing left to fix in `runSavedQuery()`. + +**Specified in `specs/2026-08-15-builtin-filters-design.md`.** Three constraints +worth knowing before opening it: a generator must answer PER ACCOUNT rather than +having its all-accounts query wrapped in a scope, or Sent double-scopes and works +only by accident of `path:` being hierarchical; Sent stays `flat` and the other +three do not, so the four match in scope and not in view mode; and changing the +account deliberately runs nothing, since the button is the verb. + +**Size: M.** ## 91. Double-clicking a thread could open it in its own window -- cgit v1.2.3