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?
- Full GTK4 Support: Latest gtk-fortran (3.24.41) includes GTK4 bindings
- Cairo Integration: Direct access to Cairo drawing API for custom rendering
- Cross-Platform: Linux, macOS, FreeBSD native support
- Active Development: Maintained by Vincent Magnin, regular updates
- Fortran-Native: High-level interface using Fortran optional arguments
- Production-Ready: Used in scientific visualization applications
🎨 SpaceSniffer Feature Analysis
Core Features (Must-Have)
-
Real-time Treemap Visualization
- Animated growth as scanning progresses
- Nested rectangles proportional to file sizes
- Smooth transitions on layout changes
-
Interactive Navigation
- Click to zoom into directories
- Breadcrumb navigation bar
- Right-click context menus
- Keyboard shortcuts (same as sniffert)
-
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
-
Scanning Features
- Background scanning with progress indicator
- Pause/resume scanning
- Skip inaccessible directories gracefully
- Show free space and unknown space
-
File Management
- Open files/directories in default app
- Delete with confirmation dialog
- Show in file manager
- Copy path to clipboard
-
Search and Filter
- Text search by filename
- Filter by file type (regex patterns)
- Filter by size range
- Filter by date range
-
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
-
Main Thread (GTK Event Loop)
- Handle all GUI events
- Process user input
- Trigger redraws (gtk_widget_queue_draw)
-
Scanning Thread (GLib Thread)
- Background directory traversal
- Periodic callbacks to main thread with updates
- Use g_idle_add for thread-safe UI updates
-
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:
-
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 -
Lighting Model
- Light source direction: L = (lx, ly, lz) - Surface normal: N = (-∂f/∂x, -∂f/∂y, 1) - Color intensity: I = ambient + diffuse * (N · L) -
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:
-
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)
-
Project Structure
- Create module skeleton
- Set up git repository structure
- Configure build system (Meson + FPM fallback)
- Create basic CI/CD workflow
-
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
-
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:
-
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
-
Background Scanning
- Implement GLib threading wrapper
- Create scan_manager for coordinating scans
- Add progress callbacks to main thread
- Test with various directory sizes
-
Progress UI
- Add progress bar to main window
- Show scan statistics (files scanned, total size)
- Implement pause/resume/cancel controls
- Add estimated time remaining
-
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:
-
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
-
Implement Cushioned Algorithm
- Research cushion function parameters
- Implement recursive cushion calculation
- Store cushion data in file_node
- Add toggle between layouts
-
Layout Manager
- Abstract layout selection
- Cache layout results
- Invalidate cache on window resize
- Implement smart recalculation (only changed subtrees)
-
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:
-
Basic Treemap Rendering
- Implement cairo_renderer module
- Draw rectangles with borders
- Render text labels (using Pango)
- Handle clipping for nested rectangles
-
Cushion Shading
- Implement lighting calculations
- Create Cairo gradients for cushions
- Add depth-based color variation
- Test different light angles
-
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
-
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)
-
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:
-
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
-
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
-
Navigation UI
- Breadcrumb bar at top
- Back/Forward buttons
- "Go up" button
- Animation on zoom transitions
-
Context Menus
- Open in file manager
- Open file with default app
- Copy path to clipboard
- Delete with confirmation
- Properties dialog (size, modified date, permissions)
-
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:
-
Search UI
- Add search entry in toolbar
- Show search results in tree view or list
- Highlight matching rectangles in treemap
- Clear search with Escape
-
Search Implementation
- Full-text filename search
- Regex pattern support
- Case-insensitive option
- Search scope (current directory vs entire tree)
-
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
-
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:
-
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)
-
Toolbar
- Add all main actions
- Icon design (consistent with GTK)
- Tooltips for all buttons
- Responsive layout (collapse on small windows)
-
Status Bar
- Show scan progress
- Show selected item details
- Show totals (files, directories, size)
- Show free space on drive
-
Error Handling
- Graceful handling of permission denied
- User-friendly error messages
- Logging for debugging
- Crash recovery (save scan state)
-
Animations
- Smooth zoom transitions
- Layout change animations
- Progress indicator animations
- Fade in/out for tooltips
-
Accessibility
- Keyboard-only navigation support
- High-contrast mode
- Screen reader compatibility (GTK accessibility API)
- Configurable font sizes
-
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:
-
Testing
- Unit tests for all modules
- Integration tests for GUI workflows
- Performance tests (1M files benchmark)
- Memory leak testing (valgrind)
- Test on multiple distributions
-
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)
-
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
-
Distribution
- Set up GitHub releases
- Create release notes
- Build CI/CD pipeline (GitHub Actions)
- Automated builds for each platform
-
Documentation
- README with screenshots
- INSTALL guide for each platform
- CONTRIBUTING guide
- LICENSE (choose appropriate)
-
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:
-
Homebrew (primary)
brew install sniffly- Submit formula to homebrew-core
- Automatic updates
- High visibility
-
MacPorts (secondary)
sudo port install sniffly
Linux:
-
Debian/Ubuntu (APT)
sudo apt install sniffly- Upload to Debian repositories
- Backport to older releases
-
Arch (AUR)
yay -S sniffly- Maintain PKGBUILD in AUR
- Community-maintained
-
Fedora/RHEL (DNF)
sudo dnf install sniffly- Submit to Fedora repositories
-
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:
- Layout algorithms (verify aspect ratios, area conservation)
- File scanning (mock filesystem)
- State management (selection, navigation)
- Color calculations (verify gradients)
- String formatting (size display)
Integration Tests
Framework: Python + GTK inspector + screenshot comparison
Test Scenarios:
- Launch app and scan /tmp
- Navigate into directory via click
- Zoom out via breadcrumb
- Switch layout algorithm
- Apply filters
- Delete file with confirmation
- Search for file
- Change color scheme
Performance Tests
Benchmarks:
- Scan 1M files (measure time, memory)
- Layout calculation (measure time for various node counts)
- Rendering (measure FPS for various node counts)
- 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
- Official Wiki: https://github.com/vmagnin/gtk-fortran/wiki
- Examples: https://github.com/vmagnin/gtk-fortran/tree/master/examples
- Mailing List: gtk-fortran-devel@lists.sourceforge.net
GTK4
- API Reference: https://docs.gtk.org/gtk4/
- Tutorial: https://www.gtk.org/docs/getting-started/
- Migration Guide (GTK3→4): https://docs.gtk.org/gtk4/migrating-3to4.html
Cairo
- API Reference: https://www.cairographics.org/manual/
- Tutorial: https://www.cairographics.org/tutorial/
- Samples: https://www.cairographics.org/samples/
Treemap Algorithms
- Squarified Treemaps: https://www.win.tue.nl/~vanwijk/stm.pdf
- Cushion Treemaps: https://www.win.tue.nl/~vanwijk/ctm.pdf
- Treemap History: http://www.cs.umd.edu/hcil/treemap-history/
🗺️ 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:
- Fortran's Versatility: Not just for scientific computing!
- Open Source Quality: Unix users deserve great tools
- Performance: Native code, no interpreter overhead
- Cross-Platform: One codebase, multiple platforms
Let's build this! 🚀
Next Steps:
- Install GTK4 and gtk-fortran
- Create minimal GTK window test
- Port core scanning logic
- 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 |