markdown · 33812 bytes Raw Blame History

SNIFFLY - Pure Fortran GUI Disk Analyzer

The SpaceSniffer Clone That Proves Fortran Can Do Anything


🎯 Project Vision

Build a near 1:1 clone of SpaceSniffer using pure Fortran with GTK4, proving that Fortran can create modern, performant GUI applications that rival commercial Windows software. Target macOS and Linux with package manager distribution.


📋 Executive Summary

What: Native GUI disk analyzer with real-time treemap visualization Why: Prove Fortran's capabilities while providing Unix users with a SpaceSniffer alternative How: gtk-fortran + GTK4 + Cairo for rendering, leveraging sniffert's proven algorithms When: 12-week development cycle with 4 major milestones Success: Native performance, handles 1M+ files, packaged for Homebrew/apt/pacman


🏗️ Technology Stack

Core Technologies

Component Technology Rationale
Language Fortran 2008+ (gfortran 9.0+) Pure Fortran philosophy, proven performance
GUI Framework GTK4 via gtk-fortran Modern, cross-platform, well-maintained
Graphics Cairo 1.18+ Hardware-accelerated 2D drawing
Build System Meson + FPM fallback GTK standard, Fortran-friendly
Dependencies GLib 2.80+, GDK4, Pango GTK ecosystem

Why gtk-fortran?

  1. Full GTK4 Support: Latest gtk-fortran (3.24.41) includes GTK4 bindings
  2. Cairo Integration: Direct access to Cairo drawing API for custom rendering
  3. Cross-Platform: Linux, macOS, FreeBSD native support
  4. Active Development: Maintained by Vincent Magnin, regular updates
  5. Fortran-Native: High-level interface using Fortran optional arguments
  6. Production-Ready: Used in scientific visualization applications

🎨 SpaceSniffer Feature Analysis

Core Features (Must-Have)

  1. Real-time Treemap Visualization

    • Animated growth as scanning progresses
    • Nested rectangles proportional to file sizes
    • Smooth transitions on layout changes
  2. Interactive Navigation

    • Click to zoom into directories
    • Breadcrumb navigation bar
    • Right-click context menus
    • Keyboard shortcuts (same as sniffert)
  3. Visual Enhancements

    • Cushioned treemap effect (3D shading)
    • Color coding by file type/age
    • Smart label placement (only when space permits)
    • Hover tooltips with full path and details
  4. Scanning Features

    • Background scanning with progress indicator
    • Pause/resume scanning
    • Skip inaccessible directories gracefully
    • Show free space and unknown space
  5. File Management

    • Open files/directories in default app
    • Delete with confirmation dialog
    • Show in file manager
    • Copy path to clipboard
  6. Search and Filter

    • Text search by filename
    • Filter by file type (regex patterns)
    • Filter by size range
    • Filter by date range
  7. Configuration

    • Layout algorithm selection (Squarified/Cushioned)
    • Color scheme customization
    • Animation speed control
    • Font size adjustment

Optional Features (Nice-to-Have)

  • Export treemap as PNG/SVG
  • Compare two directory snapshots
  • Bookmarks for frequent directories
  • Hidden files toggle
  • Multiple tabs for different scans

📐 Architecture Design

Module Structure

sniffly/
├── meson.build                 # Primary build system
├── fpm.toml                    # Fallback build system
├── app/
│   └── main.f90                # GTK application entry point
├── src/
│   ├── core/                   # Reusable from sniffert
│   │   ├── types.f90           # Core data types (file_node, rect)
│   │   ├── file_system.f90     # POSIX filesystem operations
│   │   ├── disk_scanner.f90    # Background scanning with callbacks
│   │   └── utils.f90           # String formatting, size conversion
│   │
│   ├── layout/                 # Treemap algorithms
│   │   ├── squarified.f90      # Port from sniffert (enhanced)
│   │   ├── cushioned.f90       # Cushion treemap with shading
│   │   └── layout_manager.f90  # Algorithm selection/switching
│   │
│   ├── gui/                    # GTK4 interface
│   │   ├── gtk_app.f90         # GtkApplication setup
│   │   ├── main_window.f90     # Main application window
│   │   ├── treemap_widget.f90  # Custom GtkDrawingArea widget
│   │   ├── toolbar.f90         # Top toolbar with controls
│   │   ├── statusbar.f90       # Bottom status bar
│   │   ├── dialogs.f90         # Confirmation, settings dialogs
│   │   └── menus.f90           # Context menus, menu bar
│   │
│   ├── rendering/              # Cairo drawing
│   │   ├── cairo_renderer.f90  # Core rendering engine
│   │   ├── colors.f90          # Color schemes and gradients
│   │   ├── text_layout.f90     # Pango text rendering
│   │   └── effects.f90         # Cushion shading, animations
│   │
│   └── state/                  # Application state
│       ├── app_state.f90       # Global state management
│       ├── selection.f90       # Selection and navigation
│       ├── config.f90          # User settings persistence
│       └── scan_manager.f90    # Background scan coordination
│
└── test/
    ├── test_layouts.f90        # Layout algorithm tests
    ├── test_rendering.f90      # Rendering tests
    └── test_gui.f90            # GUI interaction tests

Data Flow Architecture

┌─────────────────────────────────────────────────────────┐
│                    GTK4 Main Loop                       │
│                  (Event Processing)                     │
└─────────────────────────────────────────────────────────┘
                           │
                           ↓
┌─────────────────────────────────────────────────────────┐
│                   Main Window (GTK)                     │
│  ┌─────────────────────────────────────────────────┐   │
│  │  Toolbar: Scan Path | Layout | Color | Search  │   │
│  └─────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────┐   │
│  │         Treemap Widget (GtkDrawingArea)        │   │
│  │                                                 │   │
│  │  ┌────────────────────────────────────────┐    │   │
│  │  │   Cairo Drawing Surface               │    │   │
│  │  │   (Custom rendering via ::draw signal) │    │   │
│  │  └────────────────────────────────────────┘    │   │
│  └─────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────┐   │
│  │  Statusbar: Scanning... | Selected: /foo/bar   │   │
│  └─────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
                           │
                           ↓
┌─────────────────────────────────────────────────────────┐
│              Application State Manager                  │
│  • Current directory tree (file_node)                   │
│  • Layout cache (cached bounds)                         │
│  • Selection state (current node, breadcrumb)           │
│  • Scan progress (% complete, items scanned)            │
└─────────────────────────────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        ↓                  ↓                  ↓
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│Disk Scanner  │  │Layout Engine │  │Cairo Renderer│
│(Background   │  │(Squarified/  │  │(Drawing API) │
│ Thread)      │  │ Cushioned)   │  │              │
└──────────────┘  └──────────────┘  └──────────────┘

Threading Model

  1. Main Thread (GTK Event Loop)

    • Handle all GUI events
    • Process user input
    • Trigger redraws (gtk_widget_queue_draw)
  2. Scanning Thread (GLib Thread)

    • Background directory traversal
    • Periodic callbacks to main thread with updates
    • Use g_idle_add for thread-safe UI updates
  3. Layout Calculation

    • Triggered by scan updates or window resize
    • Can be deferred if user is interacting
    • Cache results to avoid recalculation

🎨 Treemap Algorithms

1. Squarified Treemap (Already Implemented!)

Status: Port from sniffert with minor enhancements Algorithm: Bruls et al. 2000 Advantages:

  • Excellent aspect ratios (more square rectangles)
  • Easy to compare sizes at a glance
  • Already proven in sniffert

Implementation Notes:

  • Reuse existing squarified.f90 from sniffert
  • Enhance with real-time updates (incremental layout)
  • Add smooth animation between layout changes

2. Cushioned Treemap (New Implementation)

Status: New development Algorithm: Van Wijk & Van de Wetering 1999 Visual Effect: Adds 3D shading to rectangles using bump mapping

How Cushion Shading Works:

  1. Recursive Surface Function

    For each rectangle at depth d:
    - Base surface: f(x, y) = 0
    - Add height function: h(x, y) = ax² + by²
    - Parameters a, b decrease with depth
    
  2. Lighting Model

    - Light source direction: L = (lx, ly, lz)
    - Surface normal: N = (-∂f/∂x, -∂f/∂y, 1)
    - Color intensity: I = ambient + diffuse * (N · L)
    
  3. Implementation Steps

    • Calculate cushion parameters for each node
    • Store in enhanced file_node structure
    • Apply during Cairo rendering pass

Rendering in Cairo:

! For each cushioned rectangle:
! 1. Create linear gradient based on cushion function
! 2. Apply gradient as fill pattern
! 3. Add border for clarity
cairo_pattern_create_linear(x1, y1, x2, y2)
cairo_pattern_add_color_stop_rgba(pattern, 0.0, r1, g1, b1, 1.0)
cairo_pattern_add_color_stop_rgba(pattern, 1.0, r2, g2, b2, 1.0)
cairo_set_source(cr, pattern)
cairo_rectangle(cr, x, y, w, h)
cairo_fill(cr)

🎯 Implementation Phases

Phase 1: Foundation & GTK Setup (Weeks 1-2)

Goal: Get GTK4 + gtk-fortran working with basic window

Tasks:

  1. Environment Setup

    • Install GTK4 development libraries (macOS: Homebrew, Linux: package manager)
    • Install gtk-fortran from source or package
    • Create Meson build configuration
    • Test minimal GTK app (Hello World window)
  2. Project Structure

    • Create module skeleton
    • Set up git repository structure
    • Configure build system (Meson + FPM fallback)
    • Create basic CI/CD workflow
  3. Basic GTK Application

    • Implement GtkApplication setup
    • Create main window with title bar
    • Add basic menu bar (File → Scan, Quit)
    • Test on both macOS and Linux
  4. GtkDrawingArea Integration

    • Create custom treemap widget
    • Implement ::draw signal handler
    • Test basic Cairo drawing (draw rectangle, text)
    • Verify rendering performance (target 60fps)

Success Criteria:

  • Window opens with custom drawing area
  • Can draw colored rectangles and text
  • Builds on macOS and Linux
  • No memory leaks (valgrind clean)

Estimated Time: 2 weeks


Phase 2: Core Data & Scanning (Weeks 3-4)

Goal: Port sniffert's scanning logic with GTK integration

Tasks:

  1. Port Core Modules

    • Adapt types.f90 for GUI needs
    • Port file_system.f90 unchanged
    • Port disk_scanner.f90 with callback support
    • Add thread-safe state management
  2. Background Scanning

    • Implement GLib threading wrapper
    • Create scan_manager for coordinating scans
    • Add progress callbacks to main thread
    • Test with various directory sizes
  3. Progress UI

    • Add progress bar to main window
    • Show scan statistics (files scanned, total size)
    • Implement pause/resume/cancel controls
    • Add estimated time remaining
  4. State Management

    • Implement app_state module
    • Track current directory tree
    • Handle scan updates without blocking UI
    • Add basic error handling

Success Criteria:

  • Can scan /tmp without blocking GUI
  • Progress bar updates in real-time
  • Can cancel mid-scan cleanly
  • No crashes on permission denied

Estimated Time: 2 weeks


Phase 3: Layout Algorithms (Weeks 5-6)

Goal: Implement both squarified and cushioned layouts

Tasks:

  1. Port Squarified Algorithm

    • Copy squarified.f90 from sniffert
    • Adapt for real-time updates (incremental)
    • Optimize for large datasets (1M+ nodes)
    • Add unit tests comparing to sniffert output
  2. Implement Cushioned Algorithm

    • Research cushion function parameters
    • Implement recursive cushion calculation
    • Store cushion data in file_node
    • Add toggle between layouts
  3. Layout Manager

    • Abstract layout selection
    • Cache layout results
    • Invalidate cache on window resize
    • Implement smart recalculation (only changed subtrees)
  4. Performance Optimization

    • Profile layout calculation time
    • Target < 100ms for 10k nodes
    • Use lazy evaluation for deep trees
    • Consider viewport culling for large trees

Success Criteria:

  • Both layouts produce visually correct treemaps
  • Can switch between layouts in < 1 second
  • Handles 100k files without lag
  • Layout respects window size constraints

Estimated Time: 2 weeks


Phase 4: Cairo Rendering (Weeks 7-8)

Goal: Beautiful, performant rendering with cushion effects

Tasks:

  1. Basic Treemap Rendering

    • Implement cairo_renderer module
    • Draw rectangles with borders
    • Render text labels (using Pango)
    • Handle clipping for nested rectangles
  2. Cushion Shading

    • Implement lighting calculations
    • Create Cairo gradients for cushions
    • Add depth-based color variation
    • Test different light angles
  3. Color Schemes

    • Implement file type coloring (directories, files, media, code, etc.)
    • Add color by age (old files, recent files)
    • Create multiple color schemes (Light, Dark, High Contrast)
    • Allow user customization
  4. Text Rendering

    • Use Pango for text layout
    • Smart label placement (only show when space permits)
    • Ellipsize long filenames
    • Show size labels with proper formatting (KB, MB, GB)
  5. Performance

    • Implement viewport culling (only draw visible rectangles)
    • Batch Cairo operations
    • Profile draw time (target < 16ms / 60fps)
    • Add FPS counter for debugging

Success Criteria:

  • Treemap looks beautiful with cushion effect
  • Smooth scrolling and zooming
  • Text is readable at all zoom levels
  • Maintains 60fps on 10k visible nodes

Estimated Time: 2 weeks


Phase 5: Interactivity (Weeks 9-10)

Goal: Full SpaceSniffer-style navigation and interaction

Tasks:

  1. Mouse Interaction

    • Implement hit testing (which rectangle was clicked?)
    • Single-click: select and highlight
    • Double-click: zoom into directory
    • Right-click: show context menu
    • Hover: show tooltip with details
  2. Keyboard Navigation

    • Arrow keys: navigate siblings
    • Enter: zoom into selected
    • Backspace: zoom out to parent
    • Delete: delete with confirmation (from sniffert)
    • /: focus search box
    • Escape: cancel/clear selection
  3. Navigation UI

    • Breadcrumb bar at top
    • Back/Forward buttons
    • "Go up" button
    • Animation on zoom transitions
  4. Context Menus

    • Open in file manager
    • Open file with default app
    • Copy path to clipboard
    • Delete with confirmation
    • Properties dialog (size, modified date, permissions)
  5. Selection State

    • Highlight selected rectangle
    • Show details in status bar
    • Persist selection across layout changes
    • Visual feedback on hover

Success Criteria:

  • Navigation feels smooth and intuitive
  • All keyboard shortcuts work
  • Context menu matches macOS/Linux conventions
  • No lag on interaction

Estimated Time: 2 weeks


Phase 6: Search & Filter (Week 11)

Goal: Find files quickly in large trees

Tasks:

  1. Search UI

    • Add search entry in toolbar
    • Show search results in tree view or list
    • Highlight matching rectangles in treemap
    • Clear search with Escape
  2. Search Implementation

    • Full-text filename search
    • Regex pattern support
    • Case-insensitive option
    • Search scope (current directory vs entire tree)
  3. Filtering

    • Filter by file type (extensions)
    • Filter by size range (e.g., files > 100MB)
    • Filter by date range (modified in last 7 days)
    • Combine multiple filters
  4. Filter UI

    • Filter panel in sidebar (toggleable)
    • Quick filters in toolbar (e.g., "Large files")
    • Visual indication when filters active
    • Reset filters button

Success Criteria:

  • Can find specific files in < 1 second
  • Filters work on 100k+ files
  • Search results update in real-time
  • Filter state persists across zooms

Estimated Time: 1 week


Phase 7: Polish & Configuration (Week 12)

Goal: Production-ready with user customization

Tasks:

  1. Settings Dialog

    • General: animation speed, default layout
    • Colors: scheme selection, custom colors
    • Scanning: skip patterns, depth limit
    • Save settings to config file (~/.config/sniffly/config.ini)
  2. Toolbar

    • Add all main actions
    • Icon design (consistent with GTK)
    • Tooltips for all buttons
    • Responsive layout (collapse on small windows)
  3. Status Bar

    • Show scan progress
    • Show selected item details
    • Show totals (files, directories, size)
    • Show free space on drive
  4. Error Handling

    • Graceful handling of permission denied
    • User-friendly error messages
    • Logging for debugging
    • Crash recovery (save scan state)
  5. Animations

    • Smooth zoom transitions
    • Layout change animations
    • Progress indicator animations
    • Fade in/out for tooltips
  6. Accessibility

    • Keyboard-only navigation support
    • High-contrast mode
    • Screen reader compatibility (GTK accessibility API)
    • Configurable font sizes
  7. Documentation

    • User manual (markdown)
    • Keyboard shortcuts reference
    • Build instructions
    • Developer documentation

Success Criteria:

  • App feels polished and professional
  • All settings persist correctly
  • No crashes under normal usage
  • Passes accessibility audit

Estimated Time: 1 week


Phase 8: Testing & Packaging (Weeks 13-14)

Goal: Release-ready packages for macOS and Linux

Tasks:

  1. Testing

    • Unit tests for all modules
    • Integration tests for GUI workflows
    • Performance tests (1M files benchmark)
    • Memory leak testing (valgrind)
    • Test on multiple distributions
  2. Packaging - macOS

    • Create .app bundle
    • Sign with Apple Developer ID
    • Create DMG installer
    • Homebrew formula (homebrew-core PR)
    • Test on macOS 12+ (Monterey, Ventura, Sonoma)
  3. Packaging - Linux

    • Debian package (.deb) for Ubuntu/Debian
    • RPM package (.rpm) for Fedora/RHEL
    • AUR package for Arch
    • Flatpak for universal Linux
    • AppImage for portability
  4. Distribution

    • Set up GitHub releases
    • Create release notes
    • Build CI/CD pipeline (GitHub Actions)
    • Automated builds for each platform
  5. Documentation

    • README with screenshots
    • INSTALL guide for each platform
    • CONTRIBUTING guide
    • LICENSE (choose appropriate)
  6. Marketing

    • Demo video showing features
    • Comparison with SpaceSniffer
    • Blog post: "Fortran Can Do GUIs!"
    • Submit to package managers

Success Criteria:

  • Packages install cleanly on target platforms
  • No runtime dependencies missing
  • Passes package manager guidelines
  • Downloads available from GitHub releases

Estimated Time: 2 weeks


🔧 Technical Challenges & Solutions

Challenge 1: gtk-fortran Learning Curve

Problem: gtk-fortran is less documented than GTK's C API Solution:

  • Study gtk-fortran examples repo
  • Reference GTK C documentation and translate
  • Join gtk-fortran mailing list for support
  • Contribute documentation back to project

Challenge 2: Real-time Layout Updates

Problem: Layout recalculation can be slow for large trees Solution:

  • Incremental layout updates (only changed subtrees)
  • Cache layout results aggressively
  • Use dirty flagging to track what needs recalc
  • Defer layout during rapid resizing (debounce)

Challenge 3: Memory Management

Problem: Large directory trees consume significant memory Solution:

  • Use move_alloc to avoid deep copies (already in sniffert)
  • Lazy loading for deep trees (only load visible levels)
  • Configurable depth limit
  • Manual deallocation of pruned subtrees

Challenge 4: Thread Safety with GTK

Problem: GTK is not thread-safe; can't update UI from background thread Solution:

  • Use g_idle_add to queue UI updates from scan thread
  • Wrap in gtk-fortran interface (c_funloc for callbacks)
  • Keep shared state minimal and use mutex where needed
  • Test thoroughly with ThreadSanitizer

Challenge 5: Cushion Shading Performance

Problem: Gradient calculation for each rectangle can be slow Solution:

  • Pre-calculate cushion parameters during layout
  • Use Cairo pattern caching
  • Simplify lighting model (2-stop gradients)
  • Profile and optimize hot paths

Challenge 6: Cross-Platform Differences

Problem: macOS and Linux have different GTK behaviors Solution:

  • Test on both platforms regularly (CI/CD)
  • Use GTK4's native backends (Cocoa on macOS)
  • Avoid platform-specific code where possible
  • Document known differences in README

📊 Performance Targets

Scanning Performance

Metric Target Stretch Goal
Files per second 10,000 50,000
Memory per file < 500 bytes < 300 bytes
Initial scan (100k files) < 10 seconds < 5 seconds
Background scan overhead < 5% CPU < 2% CPU

Rendering Performance

Metric Target Stretch Goal
Frame rate (1k visible nodes) 60 fps 120 fps
Frame rate (10k visible nodes) 30 fps 60 fps
Layout calculation (10k nodes) < 100ms < 50ms
Zoom animation duration 300ms 200ms

Memory Usage

Metric Target Stretch Goal
Base application memory < 50 MB < 30 MB
Per-file overhead < 500 bytes < 300 bytes
Layout cache overhead < 2x file data < 1.5x file data
Total for 1M files < 1 GB < 500 MB

🎨 Visual Design

Color Schemes

Light Theme (default on macOS)

  • Background: #FFFFFF
  • Directories: Shades of blue (#E3F2FD → #1976D2)
  • Files: Shades of green (#E8F5E9 → #388E3C)
  • Selected: Orange highlight (#FF6F00)

Dark Theme (default on Linux)

  • Background: #1E1E1E
  • Directories: Shades of purple (#4A148C → #BA68C8)
  • Files: Shades of teal (#004D40 → #26A69A)
  • Selected: Yellow highlight (#FDD835)

High Contrast Theme

  • Strong borders on all rectangles
  • High saturation colors
  • Larger fonts
  • No subtle gradients

File Type Colors

Type Extension Examples Color
Directories (N/A) Blue family
Documents .pdf, .doc, .txt Green family
Images .jpg, .png, .gif Orange family
Videos .mp4, .mkv, .avi Red family
Audio .mp3, .flac, .wav Purple family
Code .c, .py, .js, .f90 Cyan family
Archives .zip, .tar, .gz Brown family
Executables .exe, .app, .bin Gray family

Typography

  • Main Labels: System font (San Francisco on macOS, Ubuntu on Linux)
  • Size Labels: Monospace font for alignment
  • Minimum Readable Size: 10pt
  • Label Visibility: Only show when rectangle width > 60px and height > 20px

🚀 Distribution Strategy

Package Managers

macOS:

  1. Homebrew (primary)

    brew install sniffly
    
    • Submit formula to homebrew-core
    • Automatic updates
    • High visibility
  2. MacPorts (secondary)

    sudo port install sniffly
    

Linux:

  1. Debian/Ubuntu (APT)

    sudo apt install sniffly
    
    • Upload to Debian repositories
    • Backport to older releases
  2. Arch (AUR)

    yay -S sniffly
    
    • Maintain PKGBUILD in AUR
    • Community-maintained
  3. Fedora/RHEL (DNF)

    sudo dnf install sniffly
    
    • Submit to Fedora repositories
  4. Universal (Flatpak)

    flatpak install sniffly
    
    • Works on all distributions
    • Sandboxed environment

GitHub Releases

  • Provide pre-built binaries for:
    • macOS (arm64, x86_64)
    • Linux (x86_64, arm64)
  • Include source tarballs
  • Automated release via GitHub Actions
  • Semantic versioning (v1.0.0, v1.1.0, etc.)

📚 Dependencies

Build Dependencies

Dependency Version Package Name (Homebrew) Package Name (APT)
gfortran 9.0+ gcc gfortran
GTK4 4.0+ gtk4 libgtk-4-dev
gtk-fortran 3.24.41+ (build from source) (build from source)
GLib 2.80+ glib libglib2.0-dev
Cairo 1.18+ cairo libcairo2-dev
Pango 1.50+ pango libpango1.0-dev
Meson 0.60+ meson meson
Ninja 1.10+ ninja ninja-build

Runtime Dependencies

Dependency Version Included In
GTK4 runtime 4.0+ Package
GLib runtime 2.80+ Package
Cairo runtime 1.18+ Package

🧪 Testing Strategy

Unit Tests

Location: test/ directory Framework: FUnit or simple assertion framework Coverage: > 80% of non-GUI code

Test Categories:

  1. Layout algorithms (verify aspect ratios, area conservation)
  2. File scanning (mock filesystem)
  3. State management (selection, navigation)
  4. Color calculations (verify gradients)
  5. String formatting (size display)

Integration Tests

Framework: Python + GTK inspector + screenshot comparison

Test Scenarios:

  1. Launch app and scan /tmp
  2. Navigate into directory via click
  3. Zoom out via breadcrumb
  4. Switch layout algorithm
  5. Apply filters
  6. Delete file with confirmation
  7. Search for file
  8. Change color scheme

Performance Tests

Benchmarks:

  1. Scan 1M files (measure time, memory)
  2. Layout calculation (measure time for various node counts)
  3. Rendering (measure FPS for various node counts)
  4. Memory growth over time (detect leaks)

Tools:

  • gprof for profiling
  • valgrind for memory leaks
  • perf for Linux profiling
  • Instruments for macOS profiling

Manual Testing

Checklist:

  • Install on clean macOS system
  • Install on clean Ubuntu system
  • Install on clean Arch system
  • Scan various directories (/usr, /home, /Applications)
  • Resize window aggressively
  • Navigate deep directory trees
  • Delete files and verify
  • Close and reopen (verify settings persist)
  • Run for 1 hour (verify stability)

🔒 Security Considerations

File System Access

  • Principle: Only access what user explicitly scans
  • Implementation:
    • No background scanning without user action
    • Respect system permissions
    • Skip symlinks to avoid cycles
    • Warn on permission denied

Deletion Safety

  • Principle: Make it hard to delete by accident
  • Implementation:
    • Always show confirmation dialog
    • Show full path and size
    • For large deletions (>1GB), require typing name
    • No "remember my choice" option
    • Log deletions for audit trail

Sandboxing

  • Flatpak: Request filesystem access permission
  • macOS: Request Full Disk Access if needed
  • General: Run with user privileges (never root)

📈 Success Metrics

Development Success

  • All phases completed on schedule
  • No P0 bugs at launch
  • Performance targets met
  • Passes all tests on both platforms

Adoption Success

  • 1,000 stars on GitHub in first 3 months
  • 10,000 downloads in first 6 months
  • Accepted into Homebrew and apt repositories
  • Featured on Hacker News or /r/programming

Community Success

  • 5+ external contributors
  • 10+ issues/PRs from community
  • Mentioned in "Fortran can do that?" articles
  • Used as gtk-fortran showcase example

🎓 Learning Resources

gtk-fortran

GTK4

Cairo

Treemap Algorithms


🗺️ Roadmap

Version 1.0 (12 weeks)

Core features:

  • Real-time scanning with progress
  • Squarified and cushioned layouts
  • Interactive navigation (click, zoom, breadcrumb)
  • Search and filter
  • Delete with confirmation
  • Settings persistence
  • Package for macOS and Linux

Version 1.1 (Post-launch +1 month)

Polish and community feedback:

  • Bug fixes from user reports
  • Performance improvements
  • Additional color schemes
  • Export treemap as image
  • Localization support (i18n)

Version 1.2 (Post-launch +3 months)

Advanced features:

  • Compare two directory snapshots
  • Show file age heatmap
  • Bookmarks for frequent directories
  • Multiple tabs
  • Plugins/extensions system

Version 2.0 (Post-launch +6 months)

Major enhancements:

  • Network drive support
  • Cloud storage integration (investigate)
  • Advanced filters (by owner, permissions)
  • Duplicate file detection
  • Custom layout algorithms

🤝 Contributing

For Fortran Developers

This project is a showcase of Fortran's capabilities! Contributions welcome:

  • Algorithm optimizations
  • New layout algorithms
  • Performance improvements
  • Code reviews

For GUI Developers

Help make sniffly beautiful:

  • UI/UX improvements
  • Icon design
  • Color scheme contributions
  • Accessibility enhancements

For Package Maintainers

Help distribute sniffly:

  • Create packages for your favorite distro
  • Test on various platforms
  • Report packaging issues
  • Maintain downstream packages

📄 License

Recommendation: MIT or BSD-3-Clause

Rationale:

  • Permissive enough for wide adoption
  • Compatible with GTK's LGPL
  • Allows commercial use
  • Simple and well-understood

🎉 Conclusion

This project will prove that Fortran can create modern, beautiful GUI applications that rival commercial software. By combining gtk-fortran's solid bindings with your already-excellent treemap algorithms, sniffly will be a showcase of:

  1. Fortran's Versatility: Not just for scientific computing!
  2. Open Source Quality: Unix users deserve great tools
  3. Performance: Native code, no interpreter overhead
  4. Cross-Platform: One codebase, multiple platforms

Let's build this! 🚀


Next Steps:

  1. Install GTK4 and gtk-fortran
  2. Create minimal GTK window test
  3. Port core scanning logic
  4. Start Phase 1 implementation

Questions? Need help?

  • gtk-fortran community is friendly and helpful
  • GTK documentation is extensive
  • This plan is a living document - iterate as needed!

Document Version: 1.0 Last Updated: 2025-11-04 Status: Ready to Begin Development

View source
1 # SNIFFLY - Pure Fortran GUI Disk Analyzer
2 ## The SpaceSniffer Clone That Proves Fortran Can Do Anything
3
4 ---
5
6 ## 🎯 Project Vision
7
8 Build a near 1:1 clone of SpaceSniffer using **pure Fortran** with GTK4, proving that Fortran can create modern, performant GUI applications that rival commercial Windows software. Target macOS and Linux with package manager distribution.
9
10 ---
11
12 ## 📋 Executive Summary
13
14 **What:** Native GUI disk analyzer with real-time treemap visualization
15 **Why:** Prove Fortran's capabilities while providing Unix users with a SpaceSniffer alternative
16 **How:** gtk-fortran + GTK4 + Cairo for rendering, leveraging sniffert's proven algorithms
17 **When:** 12-week development cycle with 4 major milestones
18 **Success:** Native performance, handles 1M+ files, packaged for Homebrew/apt/pacman
19
20 ---
21
22 ## 🏗️ Technology Stack
23
24 ### Core Technologies
25
26 | Component | Technology | Rationale |
27 |-----------|-----------|-----------|
28 | **Language** | Fortran 2008+ (gfortran 9.0+) | Pure Fortran philosophy, proven performance |
29 | **GUI Framework** | GTK4 via gtk-fortran | Modern, cross-platform, well-maintained |
30 | **Graphics** | Cairo 1.18+ | Hardware-accelerated 2D drawing |
31 | **Build System** | Meson + FPM fallback | GTK standard, Fortran-friendly |
32 | **Dependencies** | GLib 2.80+, GDK4, Pango | GTK ecosystem |
33
34 ### Why gtk-fortran?
35
36 1. **Full GTK4 Support**: Latest gtk-fortran (3.24.41) includes GTK4 bindings
37 2. **Cairo Integration**: Direct access to Cairo drawing API for custom rendering
38 3. **Cross-Platform**: Linux, macOS, FreeBSD native support
39 4. **Active Development**: Maintained by Vincent Magnin, regular updates
40 5. **Fortran-Native**: High-level interface using Fortran optional arguments
41 6. **Production-Ready**: Used in scientific visualization applications
42
43 ---
44
45 ## 🎨 SpaceSniffer Feature Analysis
46
47 ### Core Features (Must-Have)
48
49 1. **Real-time Treemap Visualization**
50 - Animated growth as scanning progresses
51 - Nested rectangles proportional to file sizes
52 - Smooth transitions on layout changes
53
54 2. **Interactive Navigation**
55 - Click to zoom into directories
56 - Breadcrumb navigation bar
57 - Right-click context menus
58 - Keyboard shortcuts (same as sniffert)
59
60 3. **Visual Enhancements**
61 - Cushioned treemap effect (3D shading)
62 - Color coding by file type/age
63 - Smart label placement (only when space permits)
64 - Hover tooltips with full path and details
65
66 4. **Scanning Features**
67 - Background scanning with progress indicator
68 - Pause/resume scanning
69 - Skip inaccessible directories gracefully
70 - Show free space and unknown space
71
72 5. **File Management**
73 - Open files/directories in default app
74 - Delete with confirmation dialog
75 - Show in file manager
76 - Copy path to clipboard
77
78 6. **Search and Filter**
79 - Text search by filename
80 - Filter by file type (regex patterns)
81 - Filter by size range
82 - Filter by date range
83
84 7. **Configuration**
85 - Layout algorithm selection (Squarified/Cushioned)
86 - Color scheme customization
87 - Animation speed control
88 - Font size adjustment
89
90 ### Optional Features (Nice-to-Have)
91
92 - Export treemap as PNG/SVG
93 - Compare two directory snapshots
94 - Bookmarks for frequent directories
95 - Hidden files toggle
96 - Multiple tabs for different scans
97
98 ---
99
100 ## 📐 Architecture Design
101
102 ### Module Structure
103
104 ```
105 sniffly/
106 ├── meson.build # Primary build system
107 ├── fpm.toml # Fallback build system
108 ├── app/
109 │ └── main.f90 # GTK application entry point
110 ├── src/
111 │ ├── core/ # Reusable from sniffert
112 │ │ ├── types.f90 # Core data types (file_node, rect)
113 │ │ ├── file_system.f90 # POSIX filesystem operations
114 │ │ ├── disk_scanner.f90 # Background scanning with callbacks
115 │ │ └── utils.f90 # String formatting, size conversion
116 │ │
117 │ ├── layout/ # Treemap algorithms
118 │ │ ├── squarified.f90 # Port from sniffert (enhanced)
119 │ │ ├── cushioned.f90 # Cushion treemap with shading
120 │ │ └── layout_manager.f90 # Algorithm selection/switching
121 │ │
122 │ ├── gui/ # GTK4 interface
123 │ │ ├── gtk_app.f90 # GtkApplication setup
124 │ │ ├── main_window.f90 # Main application window
125 │ │ ├── treemap_widget.f90 # Custom GtkDrawingArea widget
126 │ │ ├── toolbar.f90 # Top toolbar with controls
127 │ │ ├── statusbar.f90 # Bottom status bar
128 │ │ ├── dialogs.f90 # Confirmation, settings dialogs
129 │ │ └── menus.f90 # Context menus, menu bar
130 │ │
131 │ ├── rendering/ # Cairo drawing
132 │ │ ├── cairo_renderer.f90 # Core rendering engine
133 │ │ ├── colors.f90 # Color schemes and gradients
134 │ │ ├── text_layout.f90 # Pango text rendering
135 │ │ └── effects.f90 # Cushion shading, animations
136 │ │
137 │ └── state/ # Application state
138 │ ├── app_state.f90 # Global state management
139 │ ├── selection.f90 # Selection and navigation
140 │ ├── config.f90 # User settings persistence
141 │ └── scan_manager.f90 # Background scan coordination
142
143 └── test/
144 ├── test_layouts.f90 # Layout algorithm tests
145 ├── test_rendering.f90 # Rendering tests
146 └── test_gui.f90 # GUI interaction tests
147 ```
148
149 ### Data Flow Architecture
150
151 ```
152 ┌─────────────────────────────────────────────────────────┐
153 │ GTK4 Main Loop │
154 │ (Event Processing) │
155 └─────────────────────────────────────────────────────────┘
156
157
158 ┌─────────────────────────────────────────────────────────┐
159 │ Main Window (GTK) │
160 │ ┌─────────────────────────────────────────────────┐ │
161 │ │ Toolbar: Scan Path | Layout | Color | Search │ │
162 │ └─────────────────────────────────────────────────┘ │
163 │ ┌─────────────────────────────────────────────────┐ │
164 │ │ Treemap Widget (GtkDrawingArea) │ │
165 │ │ │ │
166 │ │ ┌────────────────────────────────────────┐ │ │
167 │ │ │ Cairo Drawing Surface │ │ │
168 │ │ │ (Custom rendering via ::draw signal) │ │ │
169 │ │ └────────────────────────────────────────┘ │ │
170 │ └─────────────────────────────────────────────────┘ │
171 │ ┌─────────────────────────────────────────────────┐ │
172 │ │ Statusbar: Scanning... | Selected: /foo/bar │ │
173 │ └─────────────────────────────────────────────────┘ │
174 └─────────────────────────────────────────────────────────┘
175
176
177 ┌─────────────────────────────────────────────────────────┐
178 │ Application State Manager │
179 │ • Current directory tree (file_node) │
180 │ • Layout cache (cached bounds) │
181 │ • Selection state (current node, breadcrumb) │
182 │ • Scan progress (% complete, items scanned) │
183 └─────────────────────────────────────────────────────────┘
184
185 ┌──────────────────┼──────────────────┐
186 ↓ ↓ ↓
187 ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
188 │Disk Scanner │ │Layout Engine │ │Cairo Renderer│
189 │(Background │ │(Squarified/ │ │(Drawing API) │
190 │ Thread) │ │ Cushioned) │ │ │
191 └──────────────┘ └──────────────┘ └──────────────┘
192 ```
193
194 ### Threading Model
195
196 1. **Main Thread (GTK Event Loop)**
197 - Handle all GUI events
198 - Process user input
199 - Trigger redraws (gtk_widget_queue_draw)
200
201 2. **Scanning Thread (GLib Thread)**
202 - Background directory traversal
203 - Periodic callbacks to main thread with updates
204 - Use g_idle_add for thread-safe UI updates
205
206 3. **Layout Calculation**
207 - Triggered by scan updates or window resize
208 - Can be deferred if user is interacting
209 - Cache results to avoid recalculation
210
211 ---
212
213 ## 🎨 Treemap Algorithms
214
215 ### 1. Squarified Treemap (Already Implemented!)
216
217 **Status:** Port from sniffert with minor enhancements
218 **Algorithm:** Bruls et al. 2000
219 **Advantages:**
220 - Excellent aspect ratios (more square rectangles)
221 - Easy to compare sizes at a glance
222 - Already proven in sniffert
223
224 **Implementation Notes:**
225 - Reuse existing squarified.f90 from sniffert
226 - Enhance with real-time updates (incremental layout)
227 - Add smooth animation between layout changes
228
229 ### 2. Cushioned Treemap (New Implementation)
230
231 **Status:** New development
232 **Algorithm:** Van Wijk & Van de Wetering 1999
233 **Visual Effect:** Adds 3D shading to rectangles using bump mapping
234
235 **How Cushion Shading Works:**
236
237 1. **Recursive Surface Function**
238 ```
239 For each rectangle at depth d:
240 - Base surface: f(x, y) = 0
241 - Add height function: h(x, y) = ax² + by²
242 - Parameters a, b decrease with depth
243 ```
244
245 2. **Lighting Model**
246 ```
247 - Light source direction: L = (lx, ly, lz)
248 - Surface normal: N = (-∂f/∂x, -∂f/∂y, 1)
249 - Color intensity: I = ambient + diffuse * (N · L)
250 ```
251
252 3. **Implementation Steps**
253 - Calculate cushion parameters for each node
254 - Store in enhanced file_node structure
255 - Apply during Cairo rendering pass
256
257 **Rendering in Cairo:**
258 ```fortran
259 ! For each cushioned rectangle:
260 ! 1. Create linear gradient based on cushion function
261 ! 2. Apply gradient as fill pattern
262 ! 3. Add border for clarity
263 cairo_pattern_create_linear(x1, y1, x2, y2)
264 cairo_pattern_add_color_stop_rgba(pattern, 0.0, r1, g1, b1, 1.0)
265 cairo_pattern_add_color_stop_rgba(pattern, 1.0, r2, g2, b2, 1.0)
266 cairo_set_source(cr, pattern)
267 cairo_rectangle(cr, x, y, w, h)
268 cairo_fill(cr)
269 ```
270
271 ---
272
273 ## 🎯 Implementation Phases
274
275 ### Phase 1: Foundation & GTK Setup (Weeks 1-2)
276
277 **Goal:** Get GTK4 + gtk-fortran working with basic window
278
279 #### Tasks:
280 1. **Environment Setup**
281 - Install GTK4 development libraries (macOS: Homebrew, Linux: package manager)
282 - Install gtk-fortran from source or package
283 - Create Meson build configuration
284 - Test minimal GTK app (Hello World window)
285
286 2. **Project Structure**
287 - Create module skeleton
288 - Set up git repository structure
289 - Configure build system (Meson + FPM fallback)
290 - Create basic CI/CD workflow
291
292 3. **Basic GTK Application**
293 - Implement GtkApplication setup
294 - Create main window with title bar
295 - Add basic menu bar (File → Scan, Quit)
296 - Test on both macOS and Linux
297
298 4. **GtkDrawingArea Integration**
299 - Create custom treemap widget
300 - Implement ::draw signal handler
301 - Test basic Cairo drawing (draw rectangle, text)
302 - Verify rendering performance (target 60fps)
303
304 **Success Criteria:**
305 - Window opens with custom drawing area
306 - Can draw colored rectangles and text
307 - Builds on macOS and Linux
308 - No memory leaks (valgrind clean)
309
310 **Estimated Time:** 2 weeks
311
312 ---
313
314 ### Phase 2: Core Data & Scanning (Weeks 3-4)
315
316 **Goal:** Port sniffert's scanning logic with GTK integration
317
318 #### Tasks:
319 1. **Port Core Modules**
320 - Adapt types.f90 for GUI needs
321 - Port file_system.f90 unchanged
322 - Port disk_scanner.f90 with callback support
323 - Add thread-safe state management
324
325 2. **Background Scanning**
326 - Implement GLib threading wrapper
327 - Create scan_manager for coordinating scans
328 - Add progress callbacks to main thread
329 - Test with various directory sizes
330
331 3. **Progress UI**
332 - Add progress bar to main window
333 - Show scan statistics (files scanned, total size)
334 - Implement pause/resume/cancel controls
335 - Add estimated time remaining
336
337 4. **State Management**
338 - Implement app_state module
339 - Track current directory tree
340 - Handle scan updates without blocking UI
341 - Add basic error handling
342
343 **Success Criteria:**
344 - Can scan /tmp without blocking GUI
345 - Progress bar updates in real-time
346 - Can cancel mid-scan cleanly
347 - No crashes on permission denied
348
349 **Estimated Time:** 2 weeks
350
351 ---
352
353 ### Phase 3: Layout Algorithms (Weeks 5-6)
354
355 **Goal:** Implement both squarified and cushioned layouts
356
357 #### Tasks:
358 1. **Port Squarified Algorithm**
359 - Copy squarified.f90 from sniffert
360 - Adapt for real-time updates (incremental)
361 - Optimize for large datasets (1M+ nodes)
362 - Add unit tests comparing to sniffert output
363
364 2. **Implement Cushioned Algorithm**
365 - Research cushion function parameters
366 - Implement recursive cushion calculation
367 - Store cushion data in file_node
368 - Add toggle between layouts
369
370 3. **Layout Manager**
371 - Abstract layout selection
372 - Cache layout results
373 - Invalidate cache on window resize
374 - Implement smart recalculation (only changed subtrees)
375
376 4. **Performance Optimization**
377 - Profile layout calculation time
378 - Target < 100ms for 10k nodes
379 - Use lazy evaluation for deep trees
380 - Consider viewport culling for large trees
381
382 **Success Criteria:**
383 - Both layouts produce visually correct treemaps
384 - Can switch between layouts in < 1 second
385 - Handles 100k files without lag
386 - Layout respects window size constraints
387
388 **Estimated Time:** 2 weeks
389
390 ---
391
392 ### Phase 4: Cairo Rendering (Weeks 7-8)
393
394 **Goal:** Beautiful, performant rendering with cushion effects
395
396 #### Tasks:
397 1. **Basic Treemap Rendering**
398 - Implement cairo_renderer module
399 - Draw rectangles with borders
400 - Render text labels (using Pango)
401 - Handle clipping for nested rectangles
402
403 2. **Cushion Shading**
404 - Implement lighting calculations
405 - Create Cairo gradients for cushions
406 - Add depth-based color variation
407 - Test different light angles
408
409 3. **Color Schemes**
410 - Implement file type coloring (directories, files, media, code, etc.)
411 - Add color by age (old files, recent files)
412 - Create multiple color schemes (Light, Dark, High Contrast)
413 - Allow user customization
414
415 4. **Text Rendering**
416 - Use Pango for text layout
417 - Smart label placement (only show when space permits)
418 - Ellipsize long filenames
419 - Show size labels with proper formatting (KB, MB, GB)
420
421 5. **Performance**
422 - Implement viewport culling (only draw visible rectangles)
423 - Batch Cairo operations
424 - Profile draw time (target < 16ms / 60fps)
425 - Add FPS counter for debugging
426
427 **Success Criteria:**
428 - Treemap looks beautiful with cushion effect
429 - Smooth scrolling and zooming
430 - Text is readable at all zoom levels
431 - Maintains 60fps on 10k visible nodes
432
433 **Estimated Time:** 2 weeks
434
435 ---
436
437 ### Phase 5: Interactivity (Weeks 9-10)
438
439 **Goal:** Full SpaceSniffer-style navigation and interaction
440
441 #### Tasks:
442 1. **Mouse Interaction**
443 - Implement hit testing (which rectangle was clicked?)
444 - Single-click: select and highlight
445 - Double-click: zoom into directory
446 - Right-click: show context menu
447 - Hover: show tooltip with details
448
449 2. **Keyboard Navigation**
450 - Arrow keys: navigate siblings
451 - Enter: zoom into selected
452 - Backspace: zoom out to parent
453 - Delete: delete with confirmation (from sniffert)
454 - /: focus search box
455 - Escape: cancel/clear selection
456
457 3. **Navigation UI**
458 - Breadcrumb bar at top
459 - Back/Forward buttons
460 - "Go up" button
461 - Animation on zoom transitions
462
463 4. **Context Menus**
464 - Open in file manager
465 - Open file with default app
466 - Copy path to clipboard
467 - Delete with confirmation
468 - Properties dialog (size, modified date, permissions)
469
470 5. **Selection State**
471 - Highlight selected rectangle
472 - Show details in status bar
473 - Persist selection across layout changes
474 - Visual feedback on hover
475
476 **Success Criteria:**
477 - Navigation feels smooth and intuitive
478 - All keyboard shortcuts work
479 - Context menu matches macOS/Linux conventions
480 - No lag on interaction
481
482 **Estimated Time:** 2 weeks
483
484 ---
485
486 ### Phase 6: Search & Filter (Week 11)
487
488 **Goal:** Find files quickly in large trees
489
490 #### Tasks:
491 1. **Search UI**
492 - Add search entry in toolbar
493 - Show search results in tree view or list
494 - Highlight matching rectangles in treemap
495 - Clear search with Escape
496
497 2. **Search Implementation**
498 - Full-text filename search
499 - Regex pattern support
500 - Case-insensitive option
501 - Search scope (current directory vs entire tree)
502
503 3. **Filtering**
504 - Filter by file type (extensions)
505 - Filter by size range (e.g., files > 100MB)
506 - Filter by date range (modified in last 7 days)
507 - Combine multiple filters
508
509 4. **Filter UI**
510 - Filter panel in sidebar (toggleable)
511 - Quick filters in toolbar (e.g., "Large files")
512 - Visual indication when filters active
513 - Reset filters button
514
515 **Success Criteria:**
516 - Can find specific files in < 1 second
517 - Filters work on 100k+ files
518 - Search results update in real-time
519 - Filter state persists across zooms
520
521 **Estimated Time:** 1 week
522
523 ---
524
525 ### Phase 7: Polish & Configuration (Week 12)
526
527 **Goal:** Production-ready with user customization
528
529 #### Tasks:
530 1. **Settings Dialog**
531 - General: animation speed, default layout
532 - Colors: scheme selection, custom colors
533 - Scanning: skip patterns, depth limit
534 - Save settings to config file (~/.config/sniffly/config.ini)
535
536 2. **Toolbar**
537 - Add all main actions
538 - Icon design (consistent with GTK)
539 - Tooltips for all buttons
540 - Responsive layout (collapse on small windows)
541
542 3. **Status Bar**
543 - Show scan progress
544 - Show selected item details
545 - Show totals (files, directories, size)
546 - Show free space on drive
547
548 4. **Error Handling**
549 - Graceful handling of permission denied
550 - User-friendly error messages
551 - Logging for debugging
552 - Crash recovery (save scan state)
553
554 5. **Animations**
555 - Smooth zoom transitions
556 - Layout change animations
557 - Progress indicator animations
558 - Fade in/out for tooltips
559
560 6. **Accessibility**
561 - Keyboard-only navigation support
562 - High-contrast mode
563 - Screen reader compatibility (GTK accessibility API)
564 - Configurable font sizes
565
566 7. **Documentation**
567 - User manual (markdown)
568 - Keyboard shortcuts reference
569 - Build instructions
570 - Developer documentation
571
572 **Success Criteria:**
573 - App feels polished and professional
574 - All settings persist correctly
575 - No crashes under normal usage
576 - Passes accessibility audit
577
578 **Estimated Time:** 1 week
579
580 ---
581
582 ### Phase 8: Testing & Packaging (Weeks 13-14)
583
584 **Goal:** Release-ready packages for macOS and Linux
585
586 #### Tasks:
587 1. **Testing**
588 - Unit tests for all modules
589 - Integration tests for GUI workflows
590 - Performance tests (1M files benchmark)
591 - Memory leak testing (valgrind)
592 - Test on multiple distributions
593
594 2. **Packaging - macOS**
595 - Create .app bundle
596 - Sign with Apple Developer ID
597 - Create DMG installer
598 - Homebrew formula (homebrew-core PR)
599 - Test on macOS 12+ (Monterey, Ventura, Sonoma)
600
601 3. **Packaging - Linux**
602 - Debian package (.deb) for Ubuntu/Debian
603 - RPM package (.rpm) for Fedora/RHEL
604 - AUR package for Arch
605 - Flatpak for universal Linux
606 - AppImage for portability
607
608 4. **Distribution**
609 - Set up GitHub releases
610 - Create release notes
611 - Build CI/CD pipeline (GitHub Actions)
612 - Automated builds for each platform
613
614 5. **Documentation**
615 - README with screenshots
616 - INSTALL guide for each platform
617 - CONTRIBUTING guide
618 - LICENSE (choose appropriate)
619
620 6. **Marketing**
621 - Demo video showing features
622 - Comparison with SpaceSniffer
623 - Blog post: "Fortran Can Do GUIs!"
624 - Submit to package managers
625
626 **Success Criteria:**
627 - Packages install cleanly on target platforms
628 - No runtime dependencies missing
629 - Passes package manager guidelines
630 - Downloads available from GitHub releases
631
632 **Estimated Time:** 2 weeks
633
634 ---
635
636 ## 🔧 Technical Challenges & Solutions
637
638 ### Challenge 1: gtk-fortran Learning Curve
639
640 **Problem:** gtk-fortran is less documented than GTK's C API
641 **Solution:**
642 - Study gtk-fortran examples repo
643 - Reference GTK C documentation and translate
644 - Join gtk-fortran mailing list for support
645 - Contribute documentation back to project
646
647 ### Challenge 2: Real-time Layout Updates
648
649 **Problem:** Layout recalculation can be slow for large trees
650 **Solution:**
651 - Incremental layout updates (only changed subtrees)
652 - Cache layout results aggressively
653 - Use dirty flagging to track what needs recalc
654 - Defer layout during rapid resizing (debounce)
655
656 ### Challenge 3: Memory Management
657
658 **Problem:** Large directory trees consume significant memory
659 **Solution:**
660 - Use move_alloc to avoid deep copies (already in sniffert)
661 - Lazy loading for deep trees (only load visible levels)
662 - Configurable depth limit
663 - Manual deallocation of pruned subtrees
664
665 ### Challenge 4: Thread Safety with GTK
666
667 **Problem:** GTK is not thread-safe; can't update UI from background thread
668 **Solution:**
669 - Use g_idle_add to queue UI updates from scan thread
670 - Wrap in gtk-fortran interface (c_funloc for callbacks)
671 - Keep shared state minimal and use mutex where needed
672 - Test thoroughly with ThreadSanitizer
673
674 ### Challenge 5: Cushion Shading Performance
675
676 **Problem:** Gradient calculation for each rectangle can be slow
677 **Solution:**
678 - Pre-calculate cushion parameters during layout
679 - Use Cairo pattern caching
680 - Simplify lighting model (2-stop gradients)
681 - Profile and optimize hot paths
682
683 ### Challenge 6: Cross-Platform Differences
684
685 **Problem:** macOS and Linux have different GTK behaviors
686 **Solution:**
687 - Test on both platforms regularly (CI/CD)
688 - Use GTK4's native backends (Cocoa on macOS)
689 - Avoid platform-specific code where possible
690 - Document known differences in README
691
692 ---
693
694 ## 📊 Performance Targets
695
696 ### Scanning Performance
697
698 | Metric | Target | Stretch Goal |
699 |--------|--------|--------------|
700 | Files per second | 10,000 | 50,000 |
701 | Memory per file | < 500 bytes | < 300 bytes |
702 | Initial scan (100k files) | < 10 seconds | < 5 seconds |
703 | Background scan overhead | < 5% CPU | < 2% CPU |
704
705 ### Rendering Performance
706
707 | Metric | Target | Stretch Goal |
708 |--------|--------|--------------|
709 | Frame rate (1k visible nodes) | 60 fps | 120 fps |
710 | Frame rate (10k visible nodes) | 30 fps | 60 fps |
711 | Layout calculation (10k nodes) | < 100ms | < 50ms |
712 | Zoom animation duration | 300ms | 200ms |
713
714 ### Memory Usage
715
716 | Metric | Target | Stretch Goal |
717 |--------|--------|--------------|
718 | Base application memory | < 50 MB | < 30 MB |
719 | Per-file overhead | < 500 bytes | < 300 bytes |
720 | Layout cache overhead | < 2x file data | < 1.5x file data |
721 | Total for 1M files | < 1 GB | < 500 MB |
722
723 ---
724
725 ## 🎨 Visual Design
726
727 ### Color Schemes
728
729 **Light Theme** (default on macOS)
730 - Background: #FFFFFF
731 - Directories: Shades of blue (#E3F2FD → #1976D2)
732 - Files: Shades of green (#E8F5E9 → #388E3C)
733 - Selected: Orange highlight (#FF6F00)
734
735 **Dark Theme** (default on Linux)
736 - Background: #1E1E1E
737 - Directories: Shades of purple (#4A148C → #BA68C8)
738 - Files: Shades of teal (#004D40 → #26A69A)
739 - Selected: Yellow highlight (#FDD835)
740
741 **High Contrast Theme**
742 - Strong borders on all rectangles
743 - High saturation colors
744 - Larger fonts
745 - No subtle gradients
746
747 ### File Type Colors
748
749 | Type | Extension Examples | Color |
750 |------|-------------------|-------|
751 | Directories | (N/A) | Blue family |
752 | Documents | .pdf, .doc, .txt | Green family |
753 | Images | .jpg, .png, .gif | Orange family |
754 | Videos | .mp4, .mkv, .avi | Red family |
755 | Audio | .mp3, .flac, .wav | Purple family |
756 | Code | .c, .py, .js, .f90 | Cyan family |
757 | Archives | .zip, .tar, .gz | Brown family |
758 | Executables | .exe, .app, .bin | Gray family |
759
760 ### Typography
761
762 - **Main Labels:** System font (San Francisco on macOS, Ubuntu on Linux)
763 - **Size Labels:** Monospace font for alignment
764 - **Minimum Readable Size:** 10pt
765 - **Label Visibility:** Only show when rectangle width > 60px and height > 20px
766
767 ---
768
769 ## 🚀 Distribution Strategy
770
771 ### Package Managers
772
773 **macOS:**
774 1. **Homebrew** (primary)
775 ```bash
776 brew install sniffly
777 ```
778 - Submit formula to homebrew-core
779 - Automatic updates
780 - High visibility
781
782 2. **MacPorts** (secondary)
783 ```bash
784 sudo port install sniffly
785 ```
786
787 **Linux:**
788 1. **Debian/Ubuntu** (APT)
789 ```bash
790 sudo apt install sniffly
791 ```
792 - Upload to Debian repositories
793 - Backport to older releases
794
795 2. **Arch** (AUR)
796 ```bash
797 yay -S sniffly
798 ```
799 - Maintain PKGBUILD in AUR
800 - Community-maintained
801
802 3. **Fedora/RHEL** (DNF)
803 ```bash
804 sudo dnf install sniffly
805 ```
806 - Submit to Fedora repositories
807
808 4. **Universal** (Flatpak)
809 ```bash
810 flatpak install sniffly
811 ```
812 - Works on all distributions
813 - Sandboxed environment
814
815 ### GitHub Releases
816
817 - Provide pre-built binaries for:
818 - macOS (arm64, x86_64)
819 - Linux (x86_64, arm64)
820 - Include source tarballs
821 - Automated release via GitHub Actions
822 - Semantic versioning (v1.0.0, v1.1.0, etc.)
823
824 ---
825
826 ## 📚 Dependencies
827
828 ### Build Dependencies
829
830 | Dependency | Version | Package Name (Homebrew) | Package Name (APT) |
831 |------------|---------|-------------------------|-------------------|
832 | gfortran | 9.0+ | gcc | gfortran |
833 | GTK4 | 4.0+ | gtk4 | libgtk-4-dev |
834 | gtk-fortran | 3.24.41+ | (build from source) | (build from source) |
835 | GLib | 2.80+ | glib | libglib2.0-dev |
836 | Cairo | 1.18+ | cairo | libcairo2-dev |
837 | Pango | 1.50+ | pango | libpango1.0-dev |
838 | Meson | 0.60+ | meson | meson |
839 | Ninja | 1.10+ | ninja | ninja-build |
840
841 ### Runtime Dependencies
842
843 | Dependency | Version | Included In |
844 |------------|---------|-------------|
845 | GTK4 runtime | 4.0+ | Package |
846 | GLib runtime | 2.80+ | Package |
847 | Cairo runtime | 1.18+ | Package |
848
849 ---
850
851 ## 🧪 Testing Strategy
852
853 ### Unit Tests
854
855 **Location:** `test/` directory
856 **Framework:** FUnit or simple assertion framework
857 **Coverage:** > 80% of non-GUI code
858
859 **Test Categories:**
860 1. Layout algorithms (verify aspect ratios, area conservation)
861 2. File scanning (mock filesystem)
862 3. State management (selection, navigation)
863 4. Color calculations (verify gradients)
864 5. String formatting (size display)
865
866 ### Integration Tests
867
868 **Framework:** Python + GTK inspector + screenshot comparison
869
870 **Test Scenarios:**
871 1. Launch app and scan /tmp
872 2. Navigate into directory via click
873 3. Zoom out via breadcrumb
874 4. Switch layout algorithm
875 5. Apply filters
876 6. Delete file with confirmation
877 7. Search for file
878 8. Change color scheme
879
880 ### Performance Tests
881
882 **Benchmarks:**
883 1. Scan 1M files (measure time, memory)
884 2. Layout calculation (measure time for various node counts)
885 3. Rendering (measure FPS for various node counts)
886 4. Memory growth over time (detect leaks)
887
888 **Tools:**
889 - gprof for profiling
890 - valgrind for memory leaks
891 - perf for Linux profiling
892 - Instruments for macOS profiling
893
894 ### Manual Testing
895
896 **Checklist:**
897 - [ ] Install on clean macOS system
898 - [ ] Install on clean Ubuntu system
899 - [ ] Install on clean Arch system
900 - [ ] Scan various directories (/usr, /home, /Applications)
901 - [ ] Resize window aggressively
902 - [ ] Navigate deep directory trees
903 - [ ] Delete files and verify
904 - [ ] Close and reopen (verify settings persist)
905 - [ ] Run for 1 hour (verify stability)
906
907 ---
908
909 ## 🔒 Security Considerations
910
911 ### File System Access
912
913 - **Principle:** Only access what user explicitly scans
914 - **Implementation:**
915 - No background scanning without user action
916 - Respect system permissions
917 - Skip symlinks to avoid cycles
918 - Warn on permission denied
919
920 ### Deletion Safety
921
922 - **Principle:** Make it hard to delete by accident
923 - **Implementation:**
924 - Always show confirmation dialog
925 - Show full path and size
926 - For large deletions (>1GB), require typing name
927 - No "remember my choice" option
928 - Log deletions for audit trail
929
930 ### Sandboxing
931
932 - **Flatpak:** Request filesystem access permission
933 - **macOS:** Request Full Disk Access if needed
934 - **General:** Run with user privileges (never root)
935
936 ---
937
938 ## 📈 Success Metrics
939
940 ### Development Success
941
942 - [ ] All phases completed on schedule
943 - [ ] No P0 bugs at launch
944 - [ ] Performance targets met
945 - [ ] Passes all tests on both platforms
946
947 ### Adoption Success
948
949 - [ ] 1,000 stars on GitHub in first 3 months
950 - [ ] 10,000 downloads in first 6 months
951 - [ ] Accepted into Homebrew and apt repositories
952 - [ ] Featured on Hacker News or /r/programming
953
954 ### Community Success
955
956 - [ ] 5+ external contributors
957 - [ ] 10+ issues/PRs from community
958 - [ ] Mentioned in "Fortran can do that?" articles
959 - [ ] Used as gtk-fortran showcase example
960
961 ---
962
963 ## 🎓 Learning Resources
964
965 ### gtk-fortran
966
967 - Official Wiki: https://github.com/vmagnin/gtk-fortran/wiki
968 - Examples: https://github.com/vmagnin/gtk-fortran/tree/master/examples
969 - Mailing List: gtk-fortran-devel@lists.sourceforge.net
970
971 ### GTK4
972
973 - API Reference: https://docs.gtk.org/gtk4/
974 - Tutorial: https://www.gtk.org/docs/getting-started/
975 - Migration Guide (GTK3→4): https://docs.gtk.org/gtk4/migrating-3to4.html
976
977 ### Cairo
978
979 - API Reference: https://www.cairographics.org/manual/
980 - Tutorial: https://www.cairographics.org/tutorial/
981 - Samples: https://www.cairographics.org/samples/
982
983 ### Treemap Algorithms
984
985 - Squarified Treemaps: https://www.win.tue.nl/~vanwijk/stm.pdf
986 - Cushion Treemaps: https://www.win.tue.nl/~vanwijk/ctm.pdf
987 - Treemap History: http://www.cs.umd.edu/hcil/treemap-history/
988
989 ---
990
991 ## 🗺️ Roadmap
992
993 ### Version 1.0 (12 weeks)
994
995 Core features:
996 - Real-time scanning with progress
997 - Squarified and cushioned layouts
998 - Interactive navigation (click, zoom, breadcrumb)
999 - Search and filter
1000 - Delete with confirmation
1001 - Settings persistence
1002 - Package for macOS and Linux
1003
1004 ### Version 1.1 (Post-launch +1 month)
1005
1006 Polish and community feedback:
1007 - Bug fixes from user reports
1008 - Performance improvements
1009 - Additional color schemes
1010 - Export treemap as image
1011 - Localization support (i18n)
1012
1013 ### Version 1.2 (Post-launch +3 months)
1014
1015 Advanced features:
1016 - Compare two directory snapshots
1017 - Show file age heatmap
1018 - Bookmarks for frequent directories
1019 - Multiple tabs
1020 - Plugins/extensions system
1021
1022 ### Version 2.0 (Post-launch +6 months)
1023
1024 Major enhancements:
1025 - Network drive support
1026 - Cloud storage integration (investigate)
1027 - Advanced filters (by owner, permissions)
1028 - Duplicate file detection
1029 - Custom layout algorithms
1030
1031 ---
1032
1033 ## 🤝 Contributing
1034
1035 ### For Fortran Developers
1036
1037 This project is a showcase of Fortran's capabilities! Contributions welcome:
1038 - Algorithm optimizations
1039 - New layout algorithms
1040 - Performance improvements
1041 - Code reviews
1042
1043 ### For GUI Developers
1044
1045 Help make sniffly beautiful:
1046 - UI/UX improvements
1047 - Icon design
1048 - Color scheme contributions
1049 - Accessibility enhancements
1050
1051 ### For Package Maintainers
1052
1053 Help distribute sniffly:
1054 - Create packages for your favorite distro
1055 - Test on various platforms
1056 - Report packaging issues
1057 - Maintain downstream packages
1058
1059 ---
1060
1061 ## 📄 License
1062
1063 **Recommendation:** MIT or BSD-3-Clause
1064
1065 **Rationale:**
1066 - Permissive enough for wide adoption
1067 - Compatible with GTK's LGPL
1068 - Allows commercial use
1069 - Simple and well-understood
1070
1071 ---
1072
1073 ## 🎉 Conclusion
1074
1075 This project will prove that Fortran can create modern, beautiful GUI applications that rival commercial software. By combining gtk-fortran's solid bindings with your already-excellent treemap algorithms, sniffly will be a showcase of:
1076
1077 1. **Fortran's Versatility:** Not just for scientific computing!
1078 2. **Open Source Quality:** Unix users deserve great tools
1079 3. **Performance:** Native code, no interpreter overhead
1080 4. **Cross-Platform:** One codebase, multiple platforms
1081
1082 **Let's build this!** 🚀
1083
1084 ---
1085
1086 **Next Steps:**
1087 1. Install GTK4 and gtk-fortran
1088 2. Create minimal GTK window test
1089 3. Port core scanning logic
1090 4. Start Phase 1 implementation
1091
1092 **Questions? Need help?**
1093 - gtk-fortran community is friendly and helpful
1094 - GTK documentation is extensive
1095 - This plan is a living document - iterate as needed!
1096
1097 ---
1098
1099 **Document Version:** 1.0
1100 **Last Updated:** 2025-11-04
1101 **Status:** Ready to Begin Development