From 4f7d8560f1337eca19b10e1227115d077d6e76ad Mon Sep 17 00:00:00 2001 From: lashman Date: Fri, 27 Feb 2026 10:56:02 +0200 Subject: [PATCH] Add UI/UX overhaul design document --- .../plans/2026-02-27-ui-ux-overhaul-design.md | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 docs/plans/2026-02-27-ui-ux-overhaul-design.md diff --git a/docs/plans/2026-02-27-ui-ux-overhaul-design.md b/docs/plans/2026-02-27-ui-ux-overhaul-design.md new file mode 100644 index 0000000..a015c48 --- /dev/null +++ b/docs/plans/2026-02-27-ui-ux-overhaul-design.md @@ -0,0 +1,289 @@ +# Driftwood UI/UX Overhaul Design + +## Context + +Driftwood is a GTK4/libadwaita AppImage manager. The current UI is functional but visually plain - cards look like basic boxes, the list view resembles a settings page, and the detail view is a wall of ActionRows with no hierarchy. This design overhauls all three views plus adds a right-click context menu to make Driftwood feel like a first-class GNOME app. + +## Design Principles + +- Use libadwaita's built-in style classes wherever possible instead of custom CSS +- Follow GNOME HIG spacing (6px grid, 12px padding baseline, 14px grid gaps) +- Only show the most important information at each level (card -> list -> detail = progressive disclosure) +- Actions belong in context menus and detail headers, not crammed into cards + +--- + +## 1. Card View (Grid) + +### Current State +- 180px wide cards with 64px icons +- All badges shown (Wayland, FUSE, Update, Integration) +- Custom `.app-card` CSS duplicating libadwaita's `.card` behavior +- FlowBox allows up to 6 columns (cards get too small) + +### New Design + +``` ++----------------------------------+ +| | +| [72px icon] | +| (icon-dropshadow) | +| | +| App Name | +| (.title-3) | +| | +| 1.2.3 - 45 MiB | +| (.caption .dimmed .numeric) | +| | +| [single most important badge] | ++----------------------------------+ + 200px wide, 14px internal padding +``` + +### Changes + +- **Card width: 200px** (from 180px) for better breathing room +- **Icon size: 72px** (from 64px) with `.icon-dropshadow` class +- **App name: `.title-3`** (from `.heading`) for more visual weight +- **Version + size on one combined line** using `.caption .dimmed .numeric` +- **Single badge only** - show the most important status using priority: Update > FUSE issue > Wayland issue. Integration is already shown via the icon corner emblem +- **Replace custom `.app-card` CSS with libadwaita `.card` + `.activatable`** - native hover, active, dark mode, and contrast states for free +- **FlowBox max 4 columns** (from 6) so cards stay readable +- **14px row and column spacing** (matching GNOME Software) +- **Right-click context menu** on each card (see Section 5) + +### Files Modified +- `src/ui/app_card.rs` - card construction, badge logic, CSS classes +- `data/resources/style.css` - remove `.app-card` rules, add new sizing +- `src/ui/library_view.rs` - FlowBox max_children_per_line, context menu wiring + +--- + +## 2. List View + +### Current State +- 40px icons, standard ActionRow +- Subtitle mashes version + size + description into one hyphenated string +- All badges shown in a suffix box +- Standard ListBox (no `.rich-list`) + +### New Design + +``` ++--[48px icon]--+--Title--------------------------+--[badge]--[>]--+ +| (rounded | App Name | | +| 8px clip) | Description or path (.dimmed) | [Update] | +| | 1.2.3 - 45 MiB (.caption) | | ++---------------+----------------------------------+---------------+ +``` + +### Changes + +- **Icon size: 48px** (from 40px) with `border-radius: 8px` and `overflow: hidden` for rounded clipping +- **Subtitle structured as two lines:** + - Line 1: Description snippet or file path (dimmed) + - Line 2: Version + size (caption, dimmed, numeric) + - Use `subtitle-lines(2)` on ActionRow to allow the two-line subtitle +- **`.rich-list` style class** on the ListBox for taller rows +- **Single badge suffix** - same priority logic as cards +- **Remove integration badge from suffix** - redundant with icon emblem +- **Right-click context menu** - same menu as card view +- **Navigate arrow stays** as rightmost suffix + +### Files Modified +- `src/ui/library_view.rs` - list row construction, ListBox class, context menu +- `data/resources/style.css` - icon rounding class + +--- + +## 3. Detail View (Tabbed) + +### Current State +- 64px icon in banner +- Single scrolling page with 3 PreferencesGroups +- 20+ rows all visible at once +- No visual hierarchy between sections + +### New Design + +``` ++--[< back]------- App Name --------[Update][Launch]--+ +| | +| +--[96px icon]---+ App Name (.title-1) | +| | (icon- | 1.2.3 - x86_64 (.dimmed) | +| | dropshadow) | Short description (.body) | +| +----------------+ [Integrated] [Native Wayland] | +| | +| +---[Overview]--[System]--[Security]--[Storage]--+ | +| | | | +| | (active tab content below) | | +| | | | +| + + | ++------------------------------------------------------+ +``` + +### Hero Banner +- **96px icon** (from 64px) with `.icon-dropshadow` +- **App name in `.title-1`** (stays as-is) +- **Subtle gradient background:** `linear-gradient(to bottom, alpha(@accent_bg_color, 0.08), transparent)` behind the banner area +- **Key badges inline** (stays as-is) + +### Tab System +- **`adw::ViewStack`** contains four pages +- **`adw::ViewSwitcher`** with `.inline` style, placed between the banner and tab content (not in the header bar) +- Header bar stays clean with just back button, app name title, Update button, Launch button + +### Tab 1: Overview (default) +Shows the most commonly needed information at a glance. +- Update method (update type or "no automatic updates") +- Update status (available/up-to-date) with version info +- Last checked date +- Total launches + last launched +- AppImage type + executable status +- File path with copy + open folder buttons +- First seen / last scanned dates +- Notes (if any) + +### Tab 2: System +All system integration and compatibility information. +- Desktop integration switch +- Desktop file path (if integrated) +- Wayland compatibility row + badge +- Analyze toolkit button +- Runtime display protocol (if available) +- FUSE status + badge +- Launch method +- Firejail sandbox switch + install hint + +### Tab 3: Security +Vulnerability scanning and integrity. +- Bundled libraries count +- Vulnerability summary with severity badge +- Scan button (with busy state) +- SHA256 checksum with copy button + +### Tab 4: Storage +Disk usage and data discovery. +- AppImage file size +- Total disk footprint (if discovered) +- Discover data paths button +- Individual discovered paths with type icons, confidence badges, sizes + +### Files Modified +- `src/ui/detail_view.rs` - major restructure: banner upgrade, ViewStack/ViewSwitcher, redistribute rows across 4 tab pages +- `data/resources/style.css` - banner gradient, ViewSwitcher positioning + +--- + +## 4. CSS & Visual Polish + +### Remove +- `.app-card` and `.app-card:hover` and `.app-card:active` rules (replaced by libadwaita `.card`) +- Dark mode `.app-card` overrides (handled by `.card` automatically) +- High contrast `.app-card` overrides (handled by `.card` automatically) + +### Add +```css +/* Rounded icon clipping for list view */ +.icon-rounded { + border-radius: 8px; + overflow: hidden; +} + +/* Detail banner gradient wash */ +.detail-banner { + padding: 18px 0; + background-image: linear-gradient( + to bottom, + alpha(@accent_bg_color, 0.08), + transparent + ); + border-radius: 12px; + margin-bottom: 6px; +} +``` + +### Keep (unchanged) +- All status badge styling +- Integration emblem styling +- Letter-circle fallback icons +- All WCAG AAA styles (focus indicators, high contrast, reduced motion, target sizes) +- Compatibility warning banner +- Quick action pill styling + +### Style Classes Used (libadwaita built-in) +- `.card` + `.activatable` on FlowBoxChild card boxes +- `.icon-dropshadow` on icons 48px+ +- `.rich-list` on list view ListBox +- `.numeric` on version/size labels +- `.title-3` on card app names +- `.inline` on the detail ViewSwitcher +- `.property` on key-value ActionRows where subtitle is the main content (path, SHA256) + +--- + +## 5. Right-Click Context Menu + +### Design +A `GtkPopoverMenu` built from a `gio::Menu` model, attached to each FlowBoxChild (card) and ListBox row. Triggered by secondary click (button 3) or long-press on touch. + +``` ++---------------------------+ +| Launch | ++---------------------------+ +| Check for Updates | +| Scan for Vulnerabilities | ++---------------------------+ +| Integrate / Remove | +| Open Containing Folder | ++---------------------------+ +| Copy Path | ++---------------------------+ +``` + +### Menu Items + +| Label | Action | Notes | +|-------|--------|-------| +| Launch | `app.launch-appimage(id)` | Launches the AppImage | +| Check for Updates | `app.check-update(id)` | Triggers update check, shows toast with result | +| Scan for Vulnerabilities | `app.scan-security(id)` | Triggers security scan, shows toast | +| Integrate / Remove Integration | `app.toggle-integration(id)` | Label changes based on current state | +| Open Containing Folder | `app.open-folder(id)` | Opens file manager to the directory | +| Copy Path | `app.copy-path(id)` | Copies full path, shows toast | + +### Implementation Approach +- Define actions at the window level with the record ID as parameter +- Build a `gio::Menu` with sections (separators between groups) +- Attach `GtkPopoverMenu` to each card/row +- Wire `GtkGestureClick` for button 3 (right-click) and `GtkGestureLongPress` for touch +- Update the "Integrate/Remove" label dynamically based on `record.integrated` + +### Files Modified +- `src/window.rs` - define parameterized actions +- `src/ui/library_view.rs` - create menu model, attach to cards and rows +- `src/ui/app_card.rs` - gesture attachment on FlowBoxChild + +--- + +## 6. Files Modified Summary + +| File | Changes | +|------|---------| +| `src/ui/app_card.rs` | 72px icon, .title-3 name, single badge, .card class, gesture for context menu | +| `src/ui/library_view.rs` | FlowBox max 4 cols, .rich-list on ListBox, list row restructure, context menu creation and attachment | +| `src/ui/detail_view.rs` | 96px icon, ViewStack/ViewSwitcher tabs, redistribute rows into 4 tab pages, banner gradient | +| `src/window.rs` | Parameterized actions for context menu (launch, update, scan, integrate, open-folder, copy-path) | +| `data/resources/style.css` | Remove .app-card rules, add .icon-rounded, update .detail-banner with gradient, keep all WCAG styles | +| `src/ui/widgets.rs` | Minor - ensure icon helper supports .icon-dropshadow | + +## Verification + +After implementation: +1. `cargo build` - zero errors, zero warnings +2. `cargo test` - all 128+ tests pass +3. Visual verification of all three views in light + dark mode +4. Right-click context menu works on cards and list rows +5. Detail view tabs switch correctly, content is correctly distributed +6. Keyboard navigation: Tab through cards, Enter to open, Escape to go back +7. All WCAG AAA compliance preserved