Lays out Velox Download Manager (IDM-class download manager for Ubuntu 26.04) as a monorepo ready for parallel lane development. No implementation code by design. - docs/: architecture, roadmap M0-M7, IDM-parity GUI spec, engine design, Firefox extension spec, risks/spikes, packaging - contracts/: wire-contract skeleton (JSON Schema + fixture templates) — the single synchronization point between lanes - docs/agents/: one brief per lane (PROTO, CORE, DAEMON, GUI, EXT, PKG/QA) with owned directories, build order and definition of done - CLAUDE.md: rules of engagement — lane ownership, layering, non-negotiables - CMake scaffolding with dev/tsan/release/ci presets Two environment findings shape the design: Firefox here is the Mozilla snap (native-messaging risk, so the extension carries a loopback-WebSocket fallback), and Wayland forbids passive clipboard monitoring (so clipboard capture is explicit-action-first). Co-Authored-By: Claude Opus 5 <[email protected]>
11 KiB
03 — GUI specification (IDM parity)
Owner: lane GUI. Qt 6 Widgets, C++23.
Legal note, stated once: replicating IDM's layout, workflow and feature set is fine — UI ideas aren't protectable. Copying its icons, artwork, sounds or exact logo/branding is not. Ship an original icon set (a Papirus/Breeze-derived set under a compatible licence is the cheap route) laid out in the same positions. That gives users the muscle memory without shipping someone else's assets.
1. Main window
┌─ Velox Download Manager ─────────────────────────────────────────────── ─ □ ✕ ┐
│ Tasks File Downloads View Help │
├───────────────────────────────────────────────────────────────────────────────┤
│ [+] [▶] [⏸] [⏹] [🗑] [🗑✓] [🗓] [⚙] [🌐] │
│ Add URL Resume Pause Stop All Delete Del.Compl Scheduler Options Grabber│
├──────────────────┬────────────────────────────────────────────────────────────┤
│ ▼ All Downloads │ File Name │Q│ Size │ Status │Time Left│ Speed │Date│
│ Unfinished │ ubuntu.iso │1│ 5.8GB │ 47.2 % │ 00:03:11│ 28MB/s│... │
│ Finished │ report.pdf │ │ 2.1MB │Complete │ │ │... │
│ ▼ Categories │ track.flac │2│ 38MB │ Queued │ │ │... │
│ Compressed │ film.mkv │ │ 1.4GB │ Paused │ │ │... │
│ Documents │ │
│ Music │ │
│ Programs │ │
│ Video │ │
│ ▼ Queues │ │
│ Main Queue │ │
│ Sync Queue │ │
├──────────────────┴────────────────────────────────────────────────────────────┤
│ 4 downloads, 1 active ↓ 28.4 MB/s Limit: off Queue: running ● Connected│
└───────────────────────────────────────────────────────────────────────────────┘
Columns (reorderable, resizable, hideable, persisted): File Name · Q · Size · Status · Time Left · Transfer Rate · Last Try Date · Description. Sort on any column, ascending and descending, sort state persisted.
Implementation: QTreeView + DownloadTableModel : QAbstractItemModel fed by
event.task.progress deltas. Never rebuild the model on an event — apply a row patch and
emit dataChanged for the touched columns only. Progress bar drawn by a QStyledItemDelegate
in the Status column. Coalesce progress events on a 250 ms timer; at 20 active downloads
you get 4 repaints/sec, not 400.
Row context menu: Open · Open With · Open Folder · Move/Rename · Redownload · Refresh Download Address · Resume · Pause · Delete · Add to Queue ▸ · Properties · Copy Download URL.
Category tree: counts per node, drag a row onto a category to re-file it (moves the file on disk and updates the DB in one RPC).
2. Download File Info dialog (appears when a URL is added)
IDM's signature dialog. Populated from download.probe.
File Name: [ ubuntu-26.04-desktop-amd64.iso ]
Save As: [ /home/sami/Downloads/Programs/ ] [ Browse… ]
Category: [ Programs ▾ ] Size: 5.8 GB Resume capability: Yes
Description:[ ]
Connections:[ 8 ▾ ] Buffer: [ 4 MiB ▾ ] ☐ Remember for this file type
[ Download Now ] [ Download Later ] [ Add to Queue ▾ ] [ Cancel ]
"Download Later" = startMode: "later" (sits in the list as PAUSED_MANUAL).
Probe runs async: show the dialog immediately with a spinner in Size/Resume, fill in when
the reply lands, and never block the UI thread.
3. Download progress dialog
┌ ubuntu-26.04-desktop-amd64.iso ──────────────────────────────── ─ □ ✕ ┐
│ URL https://releases.ubuntu.com/26.04/ubuntu-26.04-…iso │
│ Status Receiving data… File size 5.80 GB │
│ Downloaded 2.74 GB (47.24 %) Transfer rate 28.41 MB/s │
│ Time left 00:03:11 Resume capability Yes │
├────────────────────────────────────────────────────────────────────────┤
│ 1 ████████████░░░░░ Receiving 3.9 MB/s │ 5 ██████████░░░░ 3.2 MB/s │
│ 2 ██████████░░░░░░░ Receiving 3.4 MB/s │ 6 ███████████░░░ 3.6 MB/s │
│ 3 █████████████░░░░ Receiving 4.1 MB/s │ 7 ████████░░░░░░ 2.9 MB/s │
│ 4 ███████████░░░░░░ Receiving 3.7 MB/s │ 8 ████████████░░ 3.5 MB/s │
├────────────────────────────────────────────────────────────────────────┤
│ [speed graph, 60 s rolling window, filled area, 1 Hz] │
├────────────────────────────────────────────────────────────────────────┤
│ ☐ Close dialog when done On completion: [ Do nothing ▾ ] │
│ [ Pause ] [ Cancel ] [ Hide ] │
└────────────────────────────────────────────────────────────────────────┘
Per-segment bars come from TaskDetail.segments[]. "On completion" offers: Do nothing /
Open file / Open folder / Exit Velox / Shut down (the last one via
org.freedesktop.login1, and it must confirm).
4. Options dialog — tabs
| Tab | Contents |
|---|---|
| General | Launch on login · minimize to tray · show floating drop target · confirm on exit · language · check for updates |
| File Types | Per-category extension lists (the auto-capture table the extension mirrors) · "Automatically start downloading these types" · MIME overrides |
| Save To | Default download directory · per-category folders · temp folder · file-exists policy (ask / rename / overwrite / resume) · "create subfolder per site" |
| Connection | Connection type preset · max connections per download (1–32) · write buffer per connection · global max concurrent downloads · timeout · retries · per-host connection overrides |
| Downloads | Speed limiter default · virus-scan command · post-download command hook · duplicate-URL policy · integrity check (MD5/SHA-256) |
| Proxy | System / manual HTTP / HTTPS / SOCKS5 / PAC · per-host bypass list |
| Site Logins | Host → username/password, stored in the Secret Service (gnome-keyring), never in SQLite |
| Sounds | Per-event sound toggles (download complete, queue complete, error) |
Everything on this dialog maps 1:1 onto settings.get/settings.set keys. The settings
key list lives in contracts/schema/types/Settings.schema.json — the GUI must not invent
a key that isn't in the schema.
5. Other windows
- Scheduler — per-queue: start time, stop time, days of week, one-time vs periodic, "hang up/exit when done", max concurrent per queue.
- Site Grabber wizard — 4 steps (project template → start URL + depth + filters → file-type filter → review found files, check what to download).
- Batch download from clipboard — parse a pasted blob of URLs, dedupe, assign category.
- Batch download with wildcards —
http://host/img{1..50}.jpgexpansion with preview. - Speed limiter — off / limit to N KB/s, with a "apply to running downloads now" button.
- Floating drop target — frameless always-on-top
QWidget, accepts dropped links, right-click menu, position remembered. IDM's drop box, minus the branding. - Tray icon — active count in tooltip, menu: Show · Add URL · Pause All · Resume All · Speed limiter ▸ · Quit (Quit asks whether to also stop the daemon).
6. Clipboard capture
QClipboard::dataChanged → if the text is a URL whose extension is in the monitored list,
show a toast: "Download this link? [Download] [Ignore]".
⚠ Under Wayland this does not work the way it does on X11 — a Wayland client is not
notified of clipboard changes made by other applications. This is the #2 risk in
docs/06-risks-and-spikes.md and has a dedicated spike. The design must therefore treat
clipboard monitoring as best-effort and ship these as the real paths:
- The extension's context menu ("Download with Velox") — covers the browser case, which is the overwhelming majority.
- A global shortcut (via
org.freedesktop.portal.GlobalShortcuts) that reads the clipboard on demand — an explicit user action, which the portal does allow. - "Add URL" dialog, pre-filled from the clipboard when it opens (also an explicit action).
7. Theming
gui/resources/qss/idm-like.qss plus a dark.qss. Follow the system light/dark preference
via QStyleHints::colorScheme(). Keep every colour in one variables block at the top of
the QSS; no hard-coded hex scattered through widget code.
8. Accessibility & i18n (M5, not optional)
Keyboard-reachable everything, Qt::AccessibleName on custom widgets, tr() from the
first commit, .ts files under gui/i18n/, RTL layout verified with Arabic.