Files
driftwood/docs/plans/2026-02-27-ui-ux-overhaul-design.md
2026-02-27 10:56:02 +02:00

11 KiB

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

/* 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