diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-07 12:48:30 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-07 12:48:30 +0200 |
| commit | de884b036689b253d10ff48daa3a05cca20ba61d (patch) | |
| tree | 1a5a5cf5020996d9f751b107e9fac9b9c466e40c /docs | |
| parent | 3826759d5167fb7a6f9449f9a39814c75771f449 (diff) | |
| download | qtmaildir-de884b036689b253d10ff48daa3a05cca20ba61d.tar.gz qtmaildir-de884b036689b253d10ff48daa3a05cca20ba61d.zip | |
fix(ui): tell read threads from unread without relying on bold
Bold was unread's only cue, and it renders identically to regular on the
user's system: confirmed by eye against a bare QTableView holding a
plain QStandardItemModel, with no code from this project involved. The
fault is in Qt or fontconfig, below this application, and nothing in the
model could ever have reached it. Read and unread mail looked exactly
alike.
The emphasis is inverted instead. Unread rows keep the palette's own
text colour and read rows are dimmed toward the background, so the cue
rides on Qt::ForegroundRole, which the delegate already honours, and
costs no column. It also suits the real ratio, measured at 99 unread
against 4220 read: dimming the bulk is calmer than highlighting it. The
dim colour is derived from the palette, never hardcoded, per the rule
item 12 established. Bold is kept for systems where it works, but
nothing depends on it now.
That exposed a second defect, visible the moment it shipped. Qt resolves
ForegroundRole into the palette and then prefers it over
HighlightedText, so a model-supplied colour wins on a SELECTED row too.
The dim is blended against the unselected background, so a selected read
row painted grey on the selection colour, near unreadable.
SubjectDelegate::initStyleOption now reverses that, and the delegate is
installed view-wide rather than on the subject column alone, so every
column gets the same handling instead of three of them keeping Qt's
ordering.
The guarding tests state the property rather than the mechanism: strip
the font from the model's answer and the two states must still differ.
A test asserting only that bold is set passes on a system where bold
paints like regular, which is exactly how this survived. The selection
test renders two rows identical but for the unread tag, selects both,
and requires zero differing pixels.
Part of item 5; the density work and the star column remain.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 40 |
1 files changed, 32 insertions, 8 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 faf510a..21e7a91 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 @@ -446,14 +446,38 @@ to copy. Two concrete sub-items, from using the list rather than looking at it: - **"All items look unread (bold), maybe use regular for read items?"** - **Check this before changing anything.** Bold is ALREADY conditional: - `ThreadListModel::data()` sets it under `Qt::FontRole` only when - `thread.isUnread()` (`src/threadlistmodel.cpp:148-152`). So either the - observation is that the user's list genuinely is mostly unread, in which case - there is no bug and the fix is elsewhere (the density work below), or bold is - leaking onto read rows through some path the model does not control. Reproduce - against a query with a known mix, e.g. `tag:inbox and not tag:unread`, before - touching the font logic. + **Done 2026-08-07, and the guess written here was wrong on both branches.** + + Bold was indeed already conditional, and the user's list was not mostly + unread, and bold was not leaking. The actual cause: **bold renders + identically to regular on the user's system.** Confirmed by eye against a + bare `QTableView` holding a plain `QStandardItemModel` with no qtmaildir code + involved, so the fault is in Qt or fontconfig, below this application, and + nothing in the model could ever have reached it. Bold was unread's ONLY cue. + + The fix inverts the emphasis instead: unread rows keep the palette's text + colour and READ rows are dimmed toward the background, via + `ThreadListModel::readColour()`. The cue rides on `Qt::ForegroundRole`, costs + no column, and suits the real ratio, which was 99 unread against 4220 read. + Bold is kept, since it works on other systems, but nothing depends on it. + + **A caution for anyone adding another `ForegroundRole` cue.** Qt resolves + that role into the palette and then prefers it over `HighlightedText`, so a + model-supplied colour wins on a SELECTED row too. The dim is blended against + the unselected background, so it landed as grey on the selection highlight, + near unreadable. `SubjectDelegate::initStyleOption` reverses that, and the + delegate is installed view-wide rather than on the subject column alone so + every column gets the same handling. + + **How this was nearly missed twice.** It was first dismissed from thread + counts, which explained why two screenshots looked alike but said nothing + about rendering. It was then dismissed again by a probe that counted lit + pixels: antialiasing makes a bold and a regular glyph light a similar number, + so the metric read "identical" regardless. Text WIDTH distinguishes them + (277px against 288px for the same string) and a strict pixel diff does; an + ink count does not. The tests that now guard this strip the font from the + model's answer entirely and require the two states to still differ, which is + the assertion that was missing all along. - **A star column for flagged threads**, mirroring the paperclip column that already exists for attachments. `ThreadSummary` carries the tags and |
