diff options
Diffstat (limited to 'docs/superpowers/plans')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 79 |
1 files changed, 43 insertions, 36 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 f559bf1..159643f 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 @@ -112,10 +112,10 @@ taking that too literally. | 52 | `test_querycompleter` fails under Wayland, passes offscreen | testing | XS | **done** | | 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 | +| 55 | In a narrow window the message pane is invisible | presentation | XS | **done** | | 56 | No action carries an icon, so the toolbar reserves space for nothing | presentation | S | **done** | | 57 | "Flag" would read better as "Important" or "Starred" | presentation | XS | **done** | -| 58 | `message_zoom` documents a 0.5 to 3.0 range and enforces none of it | correctness | XS | open | +| 58 | `message_zoom` documents a 0.5 to 3.0 range and enforces none of it | correctness | XS | **done** | | 59 | Archive and Mark all read shipped with the same icon | presentation | XS | **done** | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -3360,26 +3360,29 @@ Two notes on the verification, both worth more than the passing count: **Observed (user, 2026-08-08):** "when opening in a squared window, the left pane takes the whole width (right pane almost invisible)". -**Cause, verified in code.** The splitter is built at -`src/mainwindow.cpp:584` with `setStretchFactor(1, 2)` and **no** -`setSizes()`, and neither pane carries a minimum width. A stretch factor only -distributes space left over **after** every child's size hint is satisfied. The -thread view's hint follows its columns, which are set to fixed widths at -`src/mainwindow.cpp:557-561` and total roughly 886px (28 + 28 + 130 + 180 + -520), every one of them `Interactive` with `setStretchLastSection(false)` at -`src/mainwindow.cpp:513`. In a window narrower than that sum plus a usable -message pane there is no leftover space at all, so the stretch factor never -applies and the thread view takes essentially everything. - -This only bites on first run. Once a splitter position is saved it is restored -from `window/splitter` (`src/mainwindow.cpp:120-123`), which is why the window -behaves after the user has dragged it once. Item 1 built that persistence; it -does not supply a sane starting point. - -**Approach.** Give the message view a minimum width so the splitter cannot -collapse it, and set an initial `setSizes()` proportional to the window rather -than letting the hints decide. Sizes only apply when nothing is restored, so it -must go behind the same "no saved state" check as the geometry. +**Cause, verified in code, and NOT what this item first recorded.** The +original entry blamed the thread view's size hint, computed as the sum of its +fixed column widths (~886px) against a `setStretchFactor(1, 2)` with no leftover +space to distribute. Measured, the hint is **256px**: a `QTableView` does not +put its column sum in its size hint, so that mechanism never applied and a +freshly built window splits correctly. + +The real trigger is the **restore**, not the first run. A splitter position is +saved in pixels (`window/splitter`, `src/mainwindow.cpp:120-124`), and the +user's own state file held `1285/1252`, saved from a wide session. Reopened at +1136px, `QSplitter::restoreState()` honours the first pane's 1285 verbatim and +gives the second whatever is left, which is **29px**. That is the sliver in the +screenshot. It gets worse the wider the window ever was, which is why item 1's +persistence is where this comes from and why widening the default window would +have changed nothing. + +**Approach, as built.** A `setMinimumWidth()` on the message view plus +`setCollapsible(1, false)`, and nothing else. A restore-time repair was written +first, running from `showEvent()` because the splitter has no laid-out width +until the window is shown, and was then **deleted**: with the floor in place it +was mutation-tested to be redundant, since the minimum width constrains +`restoreState()` as much as it constrains a drag. Two mechanisms for one fault +is one too many. **Constraints.** @@ -3550,20 +3553,24 @@ independent confirmation that `flagged` is load-bearing across the suite. `toolbar_icon_size`, by reading `message_zoom` as the model for a bounded numeric key and noticing it is not bounded. -**Cause, verified in code.** `src/config.cpp:79-90` parses the value with -`toDouble()` and assigns it on success. The parse failure is reported, but -nothing checks the range. The README documents "0.5 to 3.0" (`README.md`, the -`[general]` block), and `m_messageZoom` is never clamped anywhere else: -`src/mainwindow.cpp:145` passes it straight to the saved-state default. - -So `message_zoom = 500` is accepted and applied. Unlike the toolbar icon size, -this one is recoverable, since the zoom is adjustable from the UI and the -adjusted value is what gets saved, but the first render is unusable. - -**Approach.** Clamp with a report, exactly as `toolbar_icon_size` does -(`src/config.cpp`, the `kMinToolbarIconSize`/`kMaxToolbarIconSize` block). Both -ends already have documented bounds, so this is applying the README's own -numbers. +**Cause, verified in code, and narrower than this item first recorded.** The +entry claimed the value is applied unclamped and "the first render is +unusable". It is not. `MessageView::clampZoom()` (`src/messageview.cpp:716`) +bounds every value to `kMinZoom`/`kMaxZoom`, which are 0.5 and 3.0 +(`src/messageview.h:96-97`), exactly the README's numbers, and +`MainWindow::restoreUiState()` routes the config value through +`setZoomFactor()`, so `message_zoom = 500` renders at 3.0. + +What is genuinely missing is the **report**. `src/config.cpp` parses with +`toDouble()` and, on success, assigns without comment, so nothing ever tells +the user the 500 in their file is not what they are looking at. That silence is +what the item's own Constraints section asks for. + +**Approach, as built.** Report only, no second clamp. `MessageView` owns the +bounds and already enforces them; a copy in `Config` would be free to drift +from the one that does the work, so `config.cpp` includes `messageview.h` and +reports against `MessageView::kMinZoom`/`kMaxZoom`. This is where it differs +from `toolbar_icon_size`, which has no widget-side enforcement to defer to. **Constraints.** |
