# Raspberry Pi Webkit Rendering Issues

## Problem
- Initial window displays garbled on Raspberry Pi (webkit2gtk)
- F11 temporarily clears the garbled rendering BUT does not toggle fullscreen
- F11 just redraws - never actually switches between fullscreen and windowed mode
- `--fullscreen` flag also shows garbled initially, F11 clears but never exits fullscreen

## Environment
- **Pi**: Raspberry Pi 4 (pi4c) - Debian-based OS
- **Display**: Connected via HDMI
- **Architecture**: ARM64 (aarch64)
- **Webkit**: webkit2gtk-4.0 or webkit2gtk-4.1
- **Build**: Cross-compiled via SSH from Windows

## Attempted Fixes (All Failed)

### 1. Hide/Show Window After Webview Creation
**Approach**: After building webview, hide then show window to force redraw
**Code**: main.rs lines 590-598, 659-667
```rust
#[cfg(target_os = "linux")]
{
    window.set_visible(false);
    std::thread::sleep(std::time::Duration::from_millis(50));
    window.set_visible(true);
}
```
**Result**: ❌ Still garbled on initial display

### 2. Create Window Invisible Initially (Current)
**Approach**: Use `with_visible(false)` in WindowBuilder, show after webview ready
**Code**:
- main.rs:371-376 - Create window invisible
- main.rs:590-598, 659-667 - Show after 100ms delay
```rust
// In WindowBuilder
#[cfg(target_os = "linux")]
{
    window_builder = window_builder.with_visible(false);
}

// After webview built
#[cfg(target_os = "linux")]
{
    std::thread::sleep(std::time::Duration::from_millis(100));
    window.set_visible(true);
}
```
**Result**: ❌ Still garbled (as of version 0.1.118)

### 3. GTK queue_draw() Approach (Failed to Compile)
**Approach**: Use GTK's native `queue_draw()` method
**Result**: ❌ Compilation error - `gtk` module not available in scope

## Build Infrastructure Improvements ✅

### SSH/SCP Issues Fixed
- **Problem**: SSH hostname canonicalization (`pi4c` → `pi4c.aaz.lt`)
- **Solution**: Using `spawn()` instead of `execSync()` - avoids quoting issues
- **Files**: build-pi.ts with `ssh()`, `scp()`, `sshCapture()` helper functions

### Build Process
- **Change Detection**: Compares source file mtimes - only rebuilds if Rust code changed
- **Spawn-based**: All SSH/SCP commands use spawn (no shell quoting issues)
- **Graceful Failure**: Build exits gracefully if Pi unavailable
- **Color Output**: Using `styleText()` from `node:util` instead of ANSI escapes

### Line Endings
- **Git Config**: `core.autocrlf=false`, `core.eol=lf`
- **.gitattributes**: Enforces LF for all text files

## Current Build Status
- **Version**: 0.1.118 (but Cargo.toml still shows 0.1.57 - ignored)
- **Binary**: `msger-native/bin/msgernative-arm64` (3.45 MB)
- **Build Time**: ~10 minutes on Pi
- **Versions Tested**: 0.1.116, 0.1.117, 0.1.118 - all show same garbled behavior

## Technical Details

### Version Management
- **NPM_VERSION**: Set by build.rs reading package.json at compile time
- **Single Source**: package.json is authoritative (Cargo.toml version ignored)
- **Environment Variable**: `NPM_VERSION` passed to Cargo during build

### Webkit Integration
- **Framework**: wry 0.47.2 (webview wrapper)
- **Window**: tao 0.30.8 (cross-platform window library)
- **Linux Backend**: GTK3 + webkit2gtk
- **Build GTK Method**: `builder.build_gtk(vbox)` on Linux

### F11 Handler
**Location**: main.rs:774-789
- Detects current fullscreen state
- Toggles between windowed and borderless fullscreen
- **Issue**: On Pi, F11 clears garbled rendering but doesn't actually toggle fullscreen

## Next Steps to Try

### 1. Investigate GTK Initialization
- May need to call `gtk::init()` explicitly
- Check if GTK main loop timing is the issue
- Look into webkit2gtk-specific initialization signals

### 2. WebView Load Events
- Hook into webkit's `load-changed` signal
- Show window only after page load completes
- May need to use webkit2gtk FFI directly

### 3. Different Delay Strategy
- Try longer delays (200ms, 500ms)
- Use webkit signals instead of arbitrary sleep
- Investigate if compositor/X11 needs sync

### 4. Compositor/Display Issues
- Check if running Wayland vs X11
- Test with different compositors
- May be Pi-specific display server issue

### 5. Debugging Info
- Add webkit debug environment variables
- Check for GTK warnings/errors on Pi
- Compare behavior on different Linux systems (not just Pi)

## Files Modified

### Rust Code
- `msger-native/src/main.rs`:
  - Lines 371-376: Window created invisible on Linux
  - Lines 590-598: Show window after webview (HTML mode)
  - Lines 659-667: Show window after webview (URL mode)
  - Lines 784-789: F11 fullscreen toggle

### Build Scripts
- `msger-native/build-pi.ts`:
  - Lines 12-71: spawn-based ssh/scp helpers
  - Lines 76-92: DNS debugging and SSH connection test
  - Lines 169: Source cargo env for Rust detection
  - Changed from execSync to spawn throughout

### Configuration
- `.gitattributes`: LF line endings enforced
- Git config: `autocrlf=false`, `eol=lf`

## Build Commands

### Full Build (All Platforms)
```bash
npm run build:native:all
```

### Pi Only
```bash
cd msger-native && node build-pi.ts
```

### Skip Pi if Not Available
Builds gracefully skip if Pi unreachable (exit 0)

## SSH Setup
- **Host**: pi4c (172.20.0.112)
- **Build Dir**: /tmp/msger-native-build
- **Cleanup**: Build dir removed after successful build
- **Keys**: SSH keys working (ignore libcrypto warnings)

## Dependencies on Pi
All automatically checked (warnings shown if missing):
- ✅ gcc/build-essential (C compiler)
- ✅ Rust/Cargo (sourced from ~/.cargo/env)
- ✅ pkg-config
- ✅ libglib2.0-dev, libgtk-3-dev, libwebkit2gtk-4.1-dev

## Questions to Investigate
1. Why does F11 fix rendering but not toggle fullscreen?
2. Is this a webkit2gtk bug specific to ARM64/Pi?
3. Does the issue occur on other Linux systems (x64, Wayland, etc.)?
4. Are there webkit2gtk initialization events we should wait for?
5. Is the Pi's display driver/compositor causing the issue?

## Session Timeline
- Started: 2025-11-13 ~22:00 UTC
- Last build: 2025-11-14 00:26:20 UTC
- Versions tested: 0.1.116, 0.1.117, 0.1.118
- Status: **Issue persists - no fix found yet**

## WebView Framework Alternatives (2025-11-17)

### Current Issue
GTK rendering with wry/webkit2gtk consistently garbled on Linux (Pi, WSL). Brief valid header shows, then screen corrupts.

### Attempted Fix (Failed)
- Tried `vbox.show_all()` / `vbox.show()` before `build_gtk()`
- Requires `use gtk::prelude::*` import
- Compilation issues - gtk crate not directly available in wry context
- Simple GTK method calls won't work without proper trait imports/dependencies

### WebView Alternatives (Keep WebView Capability)

**1. Tauri Framework**
- Built on wry but handles GTK setup better
- More mature, may have GTK fixes built-in
- Still uses webkit2gtk on Linux
- Worth trying - abstracts GTK complexity

**2. Native OS Dialogs (Fallback)**
- `native-dialog` crate - OS-native dialogs
- No WebView capability - simple text/buttons only
- Not suitable for HTML/URL content requirement

**3. Electron (Heavy)**
- Bundles Chromium - avoids system WebView
- Would need full rewrite from Rust to Node.js
- Most reliable but resource-heavy

**4. CEF (Chromium Embedded Framework)**
- `rust-cef` bindings
- Bundles Chromium like Electron
- Complex integration, large binaries

**5. Qt WebEngine**
- Different rendering engine (Chromium-based)
- Requires Qt framework
- Cross-platform but large dependency

**6. webkit2gtk Direct Integration**
- Bypass wry, use webkit2gtk FFI directly
- More control over GTK initialization
- Requires deep GTK/webkit knowledge

### Recommendation
Try Tauri framework first - may have solved GTK rendering issues that raw wry hasn't.

## Key Finding: Resize Fixes Rendering (2025-11-17)

**Discovery**: Msger displays garbled initially, but becomes readable after resizing past initial window dimensions.

**Implications**:
- WebKit widget renders correctly
- Initial render/compositing is corrupted
- Resize triggers proper redraw via configure-event
- Not a WebKit bug - likely GTK size allocation timing issue

**Tests Performed**:
- test13: Yellow WebKit background with hexpand/halign fill - horizontal resize works
- test14: Configure event logging - vertical resize works
- Both tests render cleanly on resize (no artifacts)

**Root Cause Hypothesis**:
- WebKit widget size negotiation happens before GTK container finalized
- Initial render uses wrong dimensions or uninitialized buffer
- Configure event forces correct size allocation and clean redraw

**Potential Fixes**:
1. Force configure event after webview creation (simulate resize)
2. Set explicit size on vbox before build_gtk()
3. Call gtk size allocation functions manually
4. Delay webview creation until after vbox realized

**Why disable HW acceleration helps in tests**:
- Software rendering more forgiving of size mismatches
- Compositor artifacts avoided
- Not ARM-specific - timing issue affects all platforms
