diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-12 09:59:56 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-12 09:59:56 +0200 |
| commit | c747c95c49e681160da8de7f4fe3eed6adc47bba (patch) | |
| tree | a05977e7d3d9c0bd17d4b3f8f77ca2d6690b2d4c /docs/superpowers/specs | |
| parent | d730ae102ecfba18399a805035552dc6e9e69543 (diff) | |
| download | quickshell-c747c95c49e681160da8de7f4fe3eed6adc47bba.tar.gz quickshell-c747c95c49e681160da8de7f4fe3eed6adc47bba.zip | |
docs: implementation plan for mail-overview
Seven tasks, ordered so the thing most likely to be wrong is checked first.
The watcher script comes before any QML because it is the only piece with a
real runnable check and needs no compositor. The component skeleton gets its
own commit because the failure it guards against is invisible: a config whose
only window is hidden exits straight after logging Configuration Loaded and
reports no error.
Two decisions changed while reading the existing components. The drawer is a
fullscreen overlay with content anchored top right, which is the idiom both
other panels use and what gives click-outside and Escape for free, rather
than a small anchored window. And its exclusionMode is Normal rather than the
Ignore those two use, so waybar's exclusive zone places it below the bar
without this component carrying the bar's 42px height as a constant to drift.
Also records a trap measured this session: notmuch exits 0 even for a
malformed query, printing something that is not a count, so every count is
validated as an integer rather than trusting the exit status. A failure that
rendered as 0 would look exactly like an empty inbox.
The live-config task needs real absolute paths, because waybar's exec and
Hyprland's Lua strings do not expand a tilde. They are written as <repo> and
<home> placeholders with a note to substitute, since the gitleaks hook blocks
committed home paths and was right to reject the first attempt.
The spec was updated to match both changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
Diffstat (limited to 'docs/superpowers/specs')
| -rw-r--r-- | docs/superpowers/specs/2026-09-12-mail-overview-design.md | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/docs/superpowers/specs/2026-09-12-mail-overview-design.md b/docs/superpowers/specs/2026-09-12-mail-overview-design.md index e5f2fa2..a691d79 100644 --- a/docs/superpowers/specs/2026-09-12-mail-overview-design.md +++ b/docs/superpowers/specs/2026-09-12-mail-overview-design.md @@ -68,6 +68,7 @@ new mail and falls as mail is read, with no polling in either case. | `mail-overview/shell.qml` | keepalive window, IpcHandler, the drawer | | `mail-overview/Accounts.qml` | parses the config, runs notmuch, exposes the model | | `mail-overview/Theme.qml` | the existing copy, unchanged | +| `mail-overview/Button.qml` | the existing copy from vm-manager, plus an enabled state | | `mail-overview/waybar-mail.sh` | continuous mode watcher script | | `mail-overview/README.md` | component notes | @@ -161,17 +162,24 @@ Left click toggles the drawer over IPC. Right click runs the sync script. ## The drawer -A `PanelWindow` anchored top and right on the primary monitor, with -`exclusionMode` set to respect other surfaces' exclusive zones while claiming -none of its own. Waybar sets an exclusive zone, so the compositor places the -drawer below it without this component knowing waybar's height. Anchoring -right puts it under the icon, which sits in `modules-right`, with no -coordinate arithmetic to go stale when the module list changes. - -Width is fixed at roughly 460px, height follows the content. - -A distinct layershell namespace, `qs-mail`, so a Hyprland layer rule can blur -it. Without the rule it renders flat translucent. +A fullscreen `PanelWindow` on the primary monitor holding a dimmed backdrop, +with the drawer itself a 460px wide rounded rectangle anchored to the +overlay's top right corner and sized to its content. That is the idiom both +other panels in this repo use, and it is what gives click-outside-to-close and +a focusable item for Escape. + +It differs from those two in one property: `exclusionMode` is `Normal` rather +than `Ignore`. Waybar claims an exclusive zone at the top of this screen +(measured at 42px), so respecting it places the whole overlay below the bar +without this component carrying the bar's height as a constant to drift. The +backdrop therefore starts below waybar, leaving the bar visible and un-dimmed. +Anchoring the drawer right puts it under the icon, which sits in +`modules-right`, with no coordinate arithmetic to go stale when the module +list changes. + +A distinct layershell namespace, `quickshell-mail`, matching the +`quickshell-*` names the other components use, so a Hyprland layer rule can +blur it. Without the rule it renders flat translucent. Escape closes it. The focus is set on the inner content item, not on the window: key events reach a focused item, and `Keys.onEscapePressed` on a @@ -235,8 +243,11 @@ inotify watch on top of the timer. ## Error handling -- notmuch missing, or the database locked: the count shows a dash, never a - zero. A zero that is actually a failure reads as "no new mail", which is the +- notmuch exits 0 even for a malformed query, printing something that is not + a count, so every count is validated as a non-negative integer and the exit + status is not the test. +- notmuch missing, the database locked, or a count that fails validation: the + count shows a dash, never a zero. A zero that is actually a failure reads as "no new mail", which is the same class of mistake as reporting a libvirt host side figure as guest memory. - config unreadable, or no `[account.*]` sections: the panel says so in one |
