markdown · 17009 bytes Raw Blame History

Sniffly Technical Stack Deep Dive

Core Stack Justification

Why Pure Fortran?

Philosophy: Prove that Fortran can build modern GUI applications that rival commercial software written in C++/C#.

Practical Advantages:

  1. Performance: Native compilation, no VM/interpreter overhead
  2. Memory Safety: Strong typing, bounds checking (with compiler flags)
  3. Existing Code: Leverage proven algorithms from sniffert
  4. Mathematical Operations: Natural for size calculations, layout algorithms
  5. Array Operations: Efficient bulk operations on file trees

Challenges Addressed:

  • String handling: Use allocatable character arrays (Fortran 2003+)
  • Pointers: Use Fortran's C interoperability for GTK callbacks
  • OOP: Use Fortran 2008 type-bound procedures where beneficial

GTK4 via gtk-fortran

Why GTK4 (not Qt, wxWidgets, etc.)?

Technical Reasons:

  1. gtk-fortran exists: Mature, maintained Fortran bindings
  2. Native on Linux: GTK is the de facto standard
  3. macOS Support: GTK4 uses native Cocoa backend
  4. Modern: GTK4 is actively developed, not legacy
  5. Cairo Integration: Built-in 2D drawing library

Comparison to Alternatives:

Framework Fortran Bindings Native Look Performance Verdict
GTK4 gtk-fortran Yes (Linux/macOS) Excellent ✅ Chosen
Qt None (would need C++ wrapper) Yes Excellent ❌ No bindings
wxWidgets None Yes Good ❌ No bindings
FLTK None No Excellent ❌ No bindings, dated look
Tk None (would need Tcl) No Poor ❌ Dated, slow

gtk-fortran Maturity:

  • First release: 2011
  • Current version: 3.24.41 (2024)
  • Active maintainer: Vincent Magnin
  • Production use: Scientific visualization tools
  • Platform support: Linux, macOS, FreeBSD, Windows (MSYS2)

GTK4 Architecture

┌─────────────────────────────────────────────────────────┐
│                    Your Fortran Code                     │
│                   (sniffly modules)                      │
└─────────────────────────────────────────────────────────┘
                           │
                           ↓ (iso_c_binding)
┌─────────────────────────────────────────────────────────┐
│                      gtk-fortran                         │
│        (Fortran interfaces to GTK C functions)           │
└─────────────────────────────────────────────────────────┘
                           │
                           ↓ (FFI)
┌─────────────────────────────────────────────────────────┐
│                    GTK4 C Library                        │
│  ┌─────────────┬──────────────┬────────────────────┐    │
│  │   Widgets   │    GDK       │      GSK           │    │
│  │  (buttons,  │  (events,    │  (GPU rendering)   │    │
│  │   windows)  │   input)     │                    │    │
│  └─────────────┴──────────────┴────────────────────┘    │
└─────────────────────────────────────────────────────────┘
                           │
                           ↓
┌─────────────────────────────────────────────────────────┐
│                    Platform Backend                      │
│   Linux: Wayland/X11    macOS: Cocoa    BSD: X11       │
└─────────────────────────────────────────────────────────┘

Cairo for 2D Graphics

Why Cairo?

Technical Strengths:

  1. Vector Graphics: Resolution-independent rendering
  2. Anti-aliasing: Beautiful, smooth edges
  3. Hardware Acceleration: GPU-backed on modern systems
  4. Compositing: Alpha blending, gradients, patterns
  5. Text Rendering: Pango integration for complex text

Cairo Features We'll Use:

Feature Usage in Sniffly
cairo_rectangle() Draw treemap rectangles
cairo_fill() Fill rectangles with color
cairo_stroke() Draw borders
cairo_set_source_rgb() Set solid colors
cairo_pattern_create_linear() Cushion gradients
cairo_clip() Clip nested rectangles
cairo_save()/restore() State management
Pango integration Render file names

Performance Characteristics:

  • Fast Paths: Solid fills, axis-aligned rectangles
  • Slow Paths: Bezier curves, complex paths (we won't use)
  • Caching: Cairo surfaces can be cached
  • Expected Performance: 60fps for 1000s of rectangles

Cairo vs. OpenGL

We chose Cairo over OpenGL because:

  • Simpler API: 2D-focused, easier to learn
  • Better Integration: Built into GTK4
  • Text Rendering: Pango support out of the box
  • Sufficient Performance: 60fps achievable for our use case

If performance becomes an issue (unlikely), we can:

  1. Use GTK4's GSK (GPU Scene Kit) backend
  2. Batch render calls
  3. Implement viewport culling (only draw visible nodes)

Pango for Text

Why Pango?

Features:

  1. Font Management: System font detection, fallbacks
  2. Text Layout: Ellipsization, wrapping, alignment
  3. Internationalization: Full Unicode support, RTL text
  4. Integration: Native Cairo rendering

Pango Features We'll Use:

! Create Pango layout
layout = pango_cairo_create_layout(cairo_context)

! Set text
call pango_layout_set_text(layout, c_str("filename.txt"))

! Set font
font_desc = pango_font_description_from_string(c_str("Sans 10"))
call pango_layout_set_font_description(layout, font_desc)

! Set ellipsization for long text
call pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END)
call pango_layout_set_width(layout, width * PANGO_SCALE)

! Render
call pango_cairo_show_layout(cairo_context, layout)

GLib for Core Utilities

Threading

GLib Threads (not pthreads) for portability:

! Start background scan thread
thread = g_thread_new(c_str("scanner"), c_funloc(scan_thread_func), c_loc(scan_data))

! Thread-safe UI updates from background thread
call g_idle_add(c_funloc(update_ui_callback), c_loc(progress_data))

Why g_idle_add?

  • GTK is not thread-safe
  • g_idle_add queues callback on main thread
  • Callback runs in GTK event loop
  • Safe to update UI from callback

Event Loop

GTK's main loop handles:

  • User input (mouse, keyboard)
  • Window events (resize, close)
  • Timers and idle callbacks
  • Background task callbacks (g_idle_add)
! Start GTK main loop (blocks until app quits)
call gtk_main()

GLib Data Structures

We'll primarily use Fortran's native arrays, but GLib provides:

  • GList/GSList: Linked lists (if needed for dynamic UI)
  • GHashTable: Hash maps (for quick file lookup)
  • GString: Dynamic strings (if Fortran strings insufficient)

Build System: Meson

Why Meson (not Make, CMake, FPM)?

Meson Advantages:

  1. GTK Standard: All GTK projects use Meson
  2. Dependency Detection: Auto-finds GTK, Cairo, etc. via pkg-config
  3. Fast: Ninja backend, parallel builds
  4. Cross-Platform: Works on Linux, macOS, BSD
  5. Clean Syntax: Python-like, easy to read

Meson vs. FPM:

  • FPM is great for pure Fortran projects
  • FPM doesn't handle C library dependencies well
  • We'll provide both Meson (primary) and FPM (fallback) builds

Sample meson.build:

project('sniffly', 'fortran',
  version: '1.0.0',
  default_options: ['warning_level=3'])

# Dependencies
gtk4_dep = dependency('gtk4')
cairo_dep = dependency('cairo')
pango_dep = dependency('pango')

# Source files
src = [
  'src/core/types.f90',
  'src/core/file_system.f90',
  'src/core/disk_scanner.f90',
  'src/layout/squarified.f90',
  'src/layout/cushioned.f90',
  'src/gui/gtk_app.f90',
  'src/rendering/cairo_renderer.f90',
  'app/main.f90',
]

# Executable
executable('sniffly', src,
  dependencies: [gtk4_dep, cairo_dep, pango_dep],
  install: true)

Building:

meson setup build
meson compile -C build
meson install -C build

Development Tools

Compiler

gfortran 9.0+ (GCC Fortran compiler)

Why gfortran?

  • Free and open source
  • Excellent Fortran 2008 support
  • C interoperability works well
  • Available on all platforms

Compiler Flags:

# Debug build
-g -Wall -Wextra -fcheck=all -fbacktrace

# Release build
-O3 -march=native -flto

Alternative: Intel Fortran (ifx) also works but not required

Debugger

GDB (GNU Debugger)

gdb ./build/sniffly

LLDB (macOS default)

lldb ./build/sniffly

Profiling

Linux: perf

perf record ./sniffly /large/directory
perf report

macOS: Instruments

instruments -t "Time Profiler" ./sniffly /large/directory

gprof (cross-platform)

# Compile with -pg flag
gfortran -pg -o sniffly ...
./sniffly /large/directory
gprof sniffly gmon.out

Memory Analysis

valgrind (Linux)

valgrind --leak-check=full ./sniffly /tmp

AddressSanitizer (both platforms)

gfortran -fsanitize=address -o sniffly ...
./sniffly /tmp

Dependency Installation

macOS (Homebrew)

# Install GTK4 and dependencies
brew install gtk4 cairo pango glib

# Install gtk-fortran (build from source)
git clone https://github.com/vmagnin/gtk-fortran.git
cd gtk-fortran
cmake -B build
cmake --build build
sudo cmake --install build

# Install build tools
brew install gfortran meson ninja

Ubuntu/Debian

# Install GTK4 and dependencies
sudo apt install libgtk-4-dev libcairo2-dev libpango1.0-dev libglib2.0-dev

# Install gtk-fortran (build from source)
git clone https://github.com/vmagnin/gtk-fortran.git
cd gtk-fortran
cmake -B build
cmake --build build
sudo cmake --install build

# Install build tools
sudo apt install gfortran meson ninja-build

Arch Linux

# Install GTK4 and dependencies
sudo pacman -S gtk4 cairo pango glib2

# gtk-fortran from AUR
yay -S gtk-fortran

# Install build tools
sudo pacman -S gcc-fortran meson ninja

Fedora/RHEL

# Install GTK4 and dependencies
sudo dnf install gtk4-devel cairo-devel pango-devel glib2-devel

# Install gtk-fortran (build from source)
git clone https://github.com/vmagnin/gtk-fortran.git
cd gtk-fortran
cmake -B build
cmake --build build
sudo cmake --install build

# Install build tools
sudo dnf install gcc-gfortran meson ninja-build

GTK4 Inspector

What is it?

  • Built-in GUI debugger for GTK apps
  • Inspect widget hierarchy
  • View CSS styles
  • Monitor signals and events
  • Performance profiling

How to Enable:

# Set environment variable
export GTK_DEBUG=interactive

# Run app (inspector opens automatically)
./sniffly

Features:

  • Widget tree browser
  • Property editor (live changes)
  • CSS inspector
  • Signal log
  • Performance metrics

Testing Infrastructure

Unit Testing: FUnit

Why FUnit?

  • Pure Fortran testing framework
  • Simple assertion API
  • Integrates with Meson

Sample Test:

module test_squarified
  use squarified
  use funit
  implicit none
contains

  @test
  subroutine test_aspect_ratio()
    real :: ratio

    ratio = aspect_ratio(10, 10)
    @assertEqual(1.0, ratio, tolerance=0.01)

    ratio = aspect_ratio(20, 10)
    @assertEqual(2.0, ratio, tolerance=0.01)
  end subroutine

end module test_squarified

Integration Testing: Python

Why Python?

  • Easy to script GTK interactions
  • Screenshot comparison libraries
  • Rich assertion libraries

Sample Test:

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, GLib
import subprocess
import time

def test_launch_and_scan():
    # Launch sniffly
    proc = subprocess.Popen(['./sniffly'])
    time.sleep(2)

    # TODO: Automate UI interaction
    # For now, manual testing with checklist

    proc.terminate()
    assert proc.returncode == 0 or proc.returncode is None

Continuous Integration

GitHub Actions Workflow

.github/workflows/build.yml:

name: Build and Test

on: [push, pull_request]

jobs:
  build-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: |
          sudo apt update
          sudo apt install -y libgtk-4-dev gfortran meson ninja-build
      - name: Build gtk-fortran
        run: |
          git clone https://github.com/vmagnin/gtk-fortran.git
          cd gtk-fortran
          cmake -B build && cmake --build build
          sudo cmake --install build
      - name: Build sniffly
        run: |
          meson setup build
          meson compile -C build
      - name: Run tests
        run: meson test -C build

  build-macos:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: |
          brew install gtk4 gfortran meson ninja
      - name: Build gtk-fortran
        run: |
          git clone https://github.com/vmagnin/gtk-fortran.git
          cd gtk-fortran
          cmake -B build && cmake --build build
          sudo cmake --install build
      - name: Build sniffly
        run: |
          meson setup build
          meson compile -C build
      - name: Run tests
        run: meson test -C build

Alternative Stacks Considered

1. Rust + gtk-rs

Pros:

  • Excellent GTK bindings
  • Memory safety guarantees
  • Growing ecosystem

Cons:

  • Not Fortran (defeats the purpose!)
  • Would need to rewrite all sniffert logic
  • Steeper learning curve

Verdict: ❌ Wrong language

2. Fortran + QML (Qt Quick)

Pros:

  • Modern declarative UI
  • Hardware-accelerated

Cons:

  • No Fortran bindings for QML
  • Would need C++/Python bridge
  • Qt is heavy dependency

Verdict: ❌ No Fortran support

3. Fortran + Web (Electron-style)

Pros:

  • HTML/CSS for UI
  • Easy prototyping

Cons:

  • Huge resource usage
  • Slow startup
  • Not native look & feel
  • Would need REST API layer

Verdict: ❌ Defeats performance goals

4. Fortran + Custom OpenGL

Pros:

  • Maximum performance
  • Full control

Cons:

  • Reinvent wheel (buttons, text input, etc.)
  • Months of UI infrastructure work
  • Platform-specific window management

Verdict: ❌ Too much work


Summary: Why This Stack is Optimal

Requirement Solution Rationale
Pure Fortran gtk-fortran Only mature Fortran GUI option
Cross-platform GTK4 Native on Linux, good on macOS
2D rendering Cairo Built-in, hardware-accelerated
Text rendering Pango Unicode, fonts, ellipsization
Build system Meson GTK standard, dependency handling
Threading GLib Safe GTK integration
Performance Native compilation No interpreter overhead
Maintainability Reuse sniffert Proven algorithms

Risk Mitigation

Risk: gtk-fortran bugs or limitations

Mitigation:

  • Join gtk-fortran community early
  • Contribute fixes upstream
  • Fallback: C shim layer for problematic functions

Risk: GTK4 not looking native on macOS

Mitigation:

  • GTK4 uses Cocoa backend (better than GTK3)
  • Test early and often on macOS
  • Accept "good enough" if perfect not achievable

Risk: Performance insufficient

Mitigation:

  • Profile early (Week 4)
  • Viewport culling for large trees
  • Consider GSK (GTK's GPU backend) if needed

Risk: Build complexity scares users

Mitigation:

  • Provide pre-built binaries
  • Package for all major package managers
  • Clear installation instructions
  • CI/CD for automated builds

Conclusion

This stack provides:

  1. Pure Fortran (proving the point)
  2. Modern GUI (GTK4)
  3. Cross-platform (macOS, Linux)
  4. Performant (native code)
  5. Maintainable (reuse sniffert)
  6. Packageable (standard tools)

We're ready to build! 🚀

View source
1 # Sniffly Technical Stack Deep Dive
2
3 ## Core Stack Justification
4
5 ### Why Pure Fortran?
6
7 **Philosophy:** Prove that Fortran can build modern GUI applications that rival commercial software written in C++/C#.
8
9 **Practical Advantages:**
10 1. **Performance:** Native compilation, no VM/interpreter overhead
11 2. **Memory Safety:** Strong typing, bounds checking (with compiler flags)
12 3. **Existing Code:** Leverage proven algorithms from sniffert
13 4. **Mathematical Operations:** Natural for size calculations, layout algorithms
14 5. **Array Operations:** Efficient bulk operations on file trees
15
16 **Challenges Addressed:**
17 - String handling: Use allocatable character arrays (Fortran 2003+)
18 - Pointers: Use Fortran's C interoperability for GTK callbacks
19 - OOP: Use Fortran 2008 type-bound procedures where beneficial
20
21 ---
22
23 ## GTK4 via gtk-fortran
24
25 ### Why GTK4 (not Qt, wxWidgets, etc.)?
26
27 **Technical Reasons:**
28 1. **gtk-fortran exists:** Mature, maintained Fortran bindings
29 2. **Native on Linux:** GTK is the de facto standard
30 3. **macOS Support:** GTK4 uses native Cocoa backend
31 4. **Modern:** GTK4 is actively developed, not legacy
32 5. **Cairo Integration:** Built-in 2D drawing library
33
34 **Comparison to Alternatives:**
35
36 | Framework | Fortran Bindings | Native Look | Performance | Verdict |
37 |-----------|-----------------|-------------|-------------|---------|
38 | GTK4 | gtk-fortran | Yes (Linux/macOS) | Excellent | ✅ Chosen |
39 | Qt | None (would need C++ wrapper) | Yes | Excellent | ❌ No bindings |
40 | wxWidgets | None | Yes | Good | ❌ No bindings |
41 | FLTK | None | No | Excellent | ❌ No bindings, dated look |
42 | Tk | None (would need Tcl) | No | Poor | ❌ Dated, slow |
43
44 **gtk-fortran Maturity:**
45 - First release: 2011
46 - Current version: 3.24.41 (2024)
47 - Active maintainer: Vincent Magnin
48 - Production use: Scientific visualization tools
49 - Platform support: Linux, macOS, FreeBSD, Windows (MSYS2)
50
51 ### GTK4 Architecture
52
53 ```
54 ┌─────────────────────────────────────────────────────────┐
55 │ Your Fortran Code │
56 │ (sniffly modules) │
57 └─────────────────────────────────────────────────────────┘
58
59 ↓ (iso_c_binding)
60 ┌─────────────────────────────────────────────────────────┐
61 │ gtk-fortran │
62 │ (Fortran interfaces to GTK C functions) │
63 └─────────────────────────────────────────────────────────┘
64
65 ↓ (FFI)
66 ┌─────────────────────────────────────────────────────────┐
67 │ GTK4 C Library │
68 │ ┌─────────────┬──────────────┬────────────────────┐ │
69 │ │ Widgets │ GDK │ GSK │ │
70 │ │ (buttons, │ (events, │ (GPU rendering) │ │
71 │ │ windows) │ input) │ │ │
72 │ └─────────────┴──────────────┴────────────────────┘ │
73 └─────────────────────────────────────────────────────────┘
74
75
76 ┌─────────────────────────────────────────────────────────┐
77 │ Platform Backend │
78 │ Linux: Wayland/X11 macOS: Cocoa BSD: X11 │
79 └─────────────────────────────────────────────────────────┘
80 ```
81
82 ---
83
84 ## Cairo for 2D Graphics
85
86 ### Why Cairo?
87
88 **Technical Strengths:**
89 1. **Vector Graphics:** Resolution-independent rendering
90 2. **Anti-aliasing:** Beautiful, smooth edges
91 3. **Hardware Acceleration:** GPU-backed on modern systems
92 4. **Compositing:** Alpha blending, gradients, patterns
93 5. **Text Rendering:** Pango integration for complex text
94
95 **Cairo Features We'll Use:**
96
97 | Feature | Usage in Sniffly |
98 |---------|-----------------|
99 | `cairo_rectangle()` | Draw treemap rectangles |
100 | `cairo_fill()` | Fill rectangles with color |
101 | `cairo_stroke()` | Draw borders |
102 | `cairo_set_source_rgb()` | Set solid colors |
103 | `cairo_pattern_create_linear()` | Cushion gradients |
104 | `cairo_clip()` | Clip nested rectangles |
105 | `cairo_save()`/`restore()` | State management |
106 | Pango integration | Render file names |
107
108 **Performance Characteristics:**
109 - **Fast Paths:** Solid fills, axis-aligned rectangles
110 - **Slow Paths:** Bezier curves, complex paths (we won't use)
111 - **Caching:** Cairo surfaces can be cached
112 - **Expected Performance:** 60fps for 1000s of rectangles
113
114 ### Cairo vs. OpenGL
115
116 We chose Cairo over OpenGL because:
117 - **Simpler API:** 2D-focused, easier to learn
118 - **Better Integration:** Built into GTK4
119 - **Text Rendering:** Pango support out of the box
120 - **Sufficient Performance:** 60fps achievable for our use case
121
122 If performance becomes an issue (unlikely), we can:
123 1. Use GTK4's GSK (GPU Scene Kit) backend
124 2. Batch render calls
125 3. Implement viewport culling (only draw visible nodes)
126
127 ---
128
129 ## Pango for Text
130
131 ### Why Pango?
132
133 **Features:**
134 1. **Font Management:** System font detection, fallbacks
135 2. **Text Layout:** Ellipsization, wrapping, alignment
136 3. **Internationalization:** Full Unicode support, RTL text
137 4. **Integration:** Native Cairo rendering
138
139 **Pango Features We'll Use:**
140
141 ```fortran
142 ! Create Pango layout
143 layout = pango_cairo_create_layout(cairo_context)
144
145 ! Set text
146 call pango_layout_set_text(layout, c_str("filename.txt"))
147
148 ! Set font
149 font_desc = pango_font_description_from_string(c_str("Sans 10"))
150 call pango_layout_set_font_description(layout, font_desc)
151
152 ! Set ellipsization for long text
153 call pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END)
154 call pango_layout_set_width(layout, width * PANGO_SCALE)
155
156 ! Render
157 call pango_cairo_show_layout(cairo_context, layout)
158 ```
159
160 ---
161
162 ## GLib for Core Utilities
163
164 ### Threading
165
166 **GLib Threads** (not pthreads) for portability:
167
168 ```fortran
169 ! Start background scan thread
170 thread = g_thread_new(c_str("scanner"), c_funloc(scan_thread_func), c_loc(scan_data))
171
172 ! Thread-safe UI updates from background thread
173 call g_idle_add(c_funloc(update_ui_callback), c_loc(progress_data))
174 ```
175
176 **Why g_idle_add?**
177 - GTK is **not thread-safe**
178 - g_idle_add queues callback on main thread
179 - Callback runs in GTK event loop
180 - Safe to update UI from callback
181
182 ### Event Loop
183
184 GTK's main loop handles:
185 - User input (mouse, keyboard)
186 - Window events (resize, close)
187 - Timers and idle callbacks
188 - Background task callbacks (g_idle_add)
189
190 ```fortran
191 ! Start GTK main loop (blocks until app quits)
192 call gtk_main()
193 ```
194
195 ### GLib Data Structures
196
197 We'll primarily use Fortran's native arrays, but GLib provides:
198 - `GList`/`GSList`: Linked lists (if needed for dynamic UI)
199 - `GHashTable`: Hash maps (for quick file lookup)
200 - `GString`: Dynamic strings (if Fortran strings insufficient)
201
202 ---
203
204 ## Build System: Meson
205
206 ### Why Meson (not Make, CMake, FPM)?
207
208 **Meson Advantages:**
209 1. **GTK Standard:** All GTK projects use Meson
210 2. **Dependency Detection:** Auto-finds GTK, Cairo, etc. via pkg-config
211 3. **Fast:** Ninja backend, parallel builds
212 4. **Cross-Platform:** Works on Linux, macOS, BSD
213 5. **Clean Syntax:** Python-like, easy to read
214
215 **Meson vs. FPM:**
216 - FPM is great for pure Fortran projects
217 - FPM doesn't handle C library dependencies well
218 - We'll provide **both** Meson (primary) and FPM (fallback) builds
219
220 **Sample meson.build:**
221
222 ```meson
223 project('sniffly', 'fortran',
224 version: '1.0.0',
225 default_options: ['warning_level=3'])
226
227 # Dependencies
228 gtk4_dep = dependency('gtk4')
229 cairo_dep = dependency('cairo')
230 pango_dep = dependency('pango')
231
232 # Source files
233 src = [
234 'src/core/types.f90',
235 'src/core/file_system.f90',
236 'src/core/disk_scanner.f90',
237 'src/layout/squarified.f90',
238 'src/layout/cushioned.f90',
239 'src/gui/gtk_app.f90',
240 'src/rendering/cairo_renderer.f90',
241 'app/main.f90',
242 ]
243
244 # Executable
245 executable('sniffly', src,
246 dependencies: [gtk4_dep, cairo_dep, pango_dep],
247 install: true)
248 ```
249
250 **Building:**
251 ```bash
252 meson setup build
253 meson compile -C build
254 meson install -C build
255 ```
256
257 ---
258
259 ## Development Tools
260
261 ### Compiler
262
263 **gfortran 9.0+** (GCC Fortran compiler)
264
265 **Why gfortran?**
266 - Free and open source
267 - Excellent Fortran 2008 support
268 - C interoperability works well
269 - Available on all platforms
270
271 **Compiler Flags:**
272 ```bash
273 # Debug build
274 -g -Wall -Wextra -fcheck=all -fbacktrace
275
276 # Release build
277 -O3 -march=native -flto
278 ```
279
280 **Alternative:** Intel Fortran (ifx) also works but not required
281
282 ### Debugger
283
284 **GDB** (GNU Debugger)
285 ```bash
286 gdb ./build/sniffly
287 ```
288
289 **LLDB** (macOS default)
290 ```bash
291 lldb ./build/sniffly
292 ```
293
294 ### Profiling
295
296 **Linux: perf**
297 ```bash
298 perf record ./sniffly /large/directory
299 perf report
300 ```
301
302 **macOS: Instruments**
303 ```bash
304 instruments -t "Time Profiler" ./sniffly /large/directory
305 ```
306
307 **gprof** (cross-platform)
308 ```bash
309 # Compile with -pg flag
310 gfortran -pg -o sniffly ...
311 ./sniffly /large/directory
312 gprof sniffly gmon.out
313 ```
314
315 ### Memory Analysis
316
317 **valgrind** (Linux)
318 ```bash
319 valgrind --leak-check=full ./sniffly /tmp
320 ```
321
322 **AddressSanitizer** (both platforms)
323 ```bash
324 gfortran -fsanitize=address -o sniffly ...
325 ./sniffly /tmp
326 ```
327
328 ---
329
330 ## Dependency Installation
331
332 ### macOS (Homebrew)
333
334 ```bash
335 # Install GTK4 and dependencies
336 brew install gtk4 cairo pango glib
337
338 # Install gtk-fortran (build from source)
339 git clone https://github.com/vmagnin/gtk-fortran.git
340 cd gtk-fortran
341 cmake -B build
342 cmake --build build
343 sudo cmake --install build
344
345 # Install build tools
346 brew install gfortran meson ninja
347 ```
348
349 ### Ubuntu/Debian
350
351 ```bash
352 # Install GTK4 and dependencies
353 sudo apt install libgtk-4-dev libcairo2-dev libpango1.0-dev libglib2.0-dev
354
355 # Install gtk-fortran (build from source)
356 git clone https://github.com/vmagnin/gtk-fortran.git
357 cd gtk-fortran
358 cmake -B build
359 cmake --build build
360 sudo cmake --install build
361
362 # Install build tools
363 sudo apt install gfortran meson ninja-build
364 ```
365
366 ### Arch Linux
367
368 ```bash
369 # Install GTK4 and dependencies
370 sudo pacman -S gtk4 cairo pango glib2
371
372 # gtk-fortran from AUR
373 yay -S gtk-fortran
374
375 # Install build tools
376 sudo pacman -S gcc-fortran meson ninja
377 ```
378
379 ### Fedora/RHEL
380
381 ```bash
382 # Install GTK4 and dependencies
383 sudo dnf install gtk4-devel cairo-devel pango-devel glib2-devel
384
385 # Install gtk-fortran (build from source)
386 git clone https://github.com/vmagnin/gtk-fortran.git
387 cd gtk-fortran
388 cmake -B build
389 cmake --build build
390 sudo cmake --install build
391
392 # Install build tools
393 sudo dnf install gcc-gfortran meson ninja-build
394 ```
395
396 ---
397
398 ## GTK4 Inspector
399
400 **What is it?**
401 - Built-in GUI debugger for GTK apps
402 - Inspect widget hierarchy
403 - View CSS styles
404 - Monitor signals and events
405 - Performance profiling
406
407 **How to Enable:**
408 ```bash
409 # Set environment variable
410 export GTK_DEBUG=interactive
411
412 # Run app (inspector opens automatically)
413 ./sniffly
414 ```
415
416 **Features:**
417 - Widget tree browser
418 - Property editor (live changes)
419 - CSS inspector
420 - Signal log
421 - Performance metrics
422
423 ---
424
425 ## Testing Infrastructure
426
427 ### Unit Testing: FUnit
428
429 **Why FUnit?**
430 - Pure Fortran testing framework
431 - Simple assertion API
432 - Integrates with Meson
433
434 **Sample Test:**
435 ```fortran
436 module test_squarified
437 use squarified
438 use funit
439 implicit none
440 contains
441
442 @test
443 subroutine test_aspect_ratio()
444 real :: ratio
445
446 ratio = aspect_ratio(10, 10)
447 @assertEqual(1.0, ratio, tolerance=0.01)
448
449 ratio = aspect_ratio(20, 10)
450 @assertEqual(2.0, ratio, tolerance=0.01)
451 end subroutine
452
453 end module test_squarified
454 ```
455
456 ### Integration Testing: Python
457
458 **Why Python?**
459 - Easy to script GTK interactions
460 - Screenshot comparison libraries
461 - Rich assertion libraries
462
463 **Sample Test:**
464 ```python
465 import gi
466 gi.require_version('Gtk', '4.0')
467 from gi.repository import Gtk, GLib
468 import subprocess
469 import time
470
471 def test_launch_and_scan():
472 # Launch sniffly
473 proc = subprocess.Popen(['./sniffly'])
474 time.sleep(2)
475
476 # TODO: Automate UI interaction
477 # For now, manual testing with checklist
478
479 proc.terminate()
480 assert proc.returncode == 0 or proc.returncode is None
481 ```
482
483 ---
484
485 ## Continuous Integration
486
487 ### GitHub Actions Workflow
488
489 **.github/workflows/build.yml:**
490 ```yaml
491 name: Build and Test
492
493 on: [push, pull_request]
494
495 jobs:
496 build-linux:
497 runs-on: ubuntu-latest
498 steps:
499 - uses: actions/checkout@v3
500 - name: Install dependencies
501 run: |
502 sudo apt update
503 sudo apt install -y libgtk-4-dev gfortran meson ninja-build
504 - name: Build gtk-fortran
505 run: |
506 git clone https://github.com/vmagnin/gtk-fortran.git
507 cd gtk-fortran
508 cmake -B build && cmake --build build
509 sudo cmake --install build
510 - name: Build sniffly
511 run: |
512 meson setup build
513 meson compile -C build
514 - name: Run tests
515 run: meson test -C build
516
517 build-macos:
518 runs-on: macos-latest
519 steps:
520 - uses: actions/checkout@v3
521 - name: Install dependencies
522 run: |
523 brew install gtk4 gfortran meson ninja
524 - name: Build gtk-fortran
525 run: |
526 git clone https://github.com/vmagnin/gtk-fortran.git
527 cd gtk-fortran
528 cmake -B build && cmake --build build
529 sudo cmake --install build
530 - name: Build sniffly
531 run: |
532 meson setup build
533 meson compile -C build
534 - name: Run tests
535 run: meson test -C build
536 ```
537
538 ---
539
540 ## Alternative Stacks Considered
541
542 ### 1. Rust + gtk-rs
543
544 **Pros:**
545 - Excellent GTK bindings
546 - Memory safety guarantees
547 - Growing ecosystem
548
549 **Cons:**
550 - Not Fortran (defeats the purpose!)
551 - Would need to rewrite all sniffert logic
552 - Steeper learning curve
553
554 **Verdict:** ❌ Wrong language
555
556 ### 2. Fortran + QML (Qt Quick)
557
558 **Pros:**
559 - Modern declarative UI
560 - Hardware-accelerated
561
562 **Cons:**
563 - No Fortran bindings for QML
564 - Would need C++/Python bridge
565 - Qt is heavy dependency
566
567 **Verdict:** ❌ No Fortran support
568
569 ### 3. Fortran + Web (Electron-style)
570
571 **Pros:**
572 - HTML/CSS for UI
573 - Easy prototyping
574
575 **Cons:**
576 - Huge resource usage
577 - Slow startup
578 - Not native look & feel
579 - Would need REST API layer
580
581 **Verdict:** ❌ Defeats performance goals
582
583 ### 4. Fortran + Custom OpenGL
584
585 **Pros:**
586 - Maximum performance
587 - Full control
588
589 **Cons:**
590 - Reinvent wheel (buttons, text input, etc.)
591 - Months of UI infrastructure work
592 - Platform-specific window management
593
594 **Verdict:** ❌ Too much work
595
596 ---
597
598 ## Summary: Why This Stack is Optimal
599
600 | Requirement | Solution | Rationale |
601 |-------------|----------|-----------|
602 | Pure Fortran | gtk-fortran | Only mature Fortran GUI option |
603 | Cross-platform | GTK4 | Native on Linux, good on macOS |
604 | 2D rendering | Cairo | Built-in, hardware-accelerated |
605 | Text rendering | Pango | Unicode, fonts, ellipsization |
606 | Build system | Meson | GTK standard, dependency handling |
607 | Threading | GLib | Safe GTK integration |
608 | Performance | Native compilation | No interpreter overhead |
609 | Maintainability | Reuse sniffert | Proven algorithms |
610
611 ---
612
613 ## Risk Mitigation
614
615 ### Risk: gtk-fortran bugs or limitations
616
617 **Mitigation:**
618 - Join gtk-fortran community early
619 - Contribute fixes upstream
620 - Fallback: C shim layer for problematic functions
621
622 ### Risk: GTK4 not looking native on macOS
623
624 **Mitigation:**
625 - GTK4 uses Cocoa backend (better than GTK3)
626 - Test early and often on macOS
627 - Accept "good enough" if perfect not achievable
628
629 ### Risk: Performance insufficient
630
631 **Mitigation:**
632 - Profile early (Week 4)
633 - Viewport culling for large trees
634 - Consider GSK (GTK's GPU backend) if needed
635
636 ### Risk: Build complexity scares users
637
638 **Mitigation:**
639 - Provide pre-built binaries
640 - Package for all major package managers
641 - Clear installation instructions
642 - CI/CD for automated builds
643
644 ---
645
646 ## Conclusion
647
648 This stack provides:
649 1.**Pure Fortran** (proving the point)
650 2.**Modern GUI** (GTK4)
651 3.**Cross-platform** (macOS, Linux)
652 4.**Performant** (native code)
653 5.**Maintainable** (reuse sniffert)
654 6.**Packageable** (standard tools)
655
656 **We're ready to build!** 🚀