wrtype 0.1.0

A Rust implementation of wtype - a Wayland virtual keyboard tool that types text and sends key events
Documentation
# Architecture Overview

wrtype is designed as a modular, well-structured Rust application that implements the Wayland virtual keyboard protocol. This document provides a comprehensive overview of the system architecture, design decisions, and implementation details.

## High-Level Architecture

```mermaid
graph TD
    A[CLI Input] --> B[Command Parser]
    B --> C[Command Executor]
    C --> D[Keymap Builder]
    C --> E[Wayland State]
    D --> F[XKB Keymap]
    E --> G[Virtual Keyboard Protocol]
    F --> G
    G --> H[Wayland Compositor]
    H --> I[Target Application]
```

wrtype follows a pipeline architecture where data flows from command-line input through various processing stages to ultimately generate Wayland keyboard events.

## Core Components

### 1. Main Module (`main.rs`)

**Responsibilities:**
- Command-line argument parsing using `clap`
- Input validation and preprocessing
- Command sequence generation
- Application lifecycle management

**Key Types:**
- `Args` - Structured CLI arguments
- `Command` - Internal command representation
- `Modifier` - Keyboard modifier enumeration

```rust
pub enum Command {
    Text { text: String, delay: Duration },
    ModPress(Modifier),
    ModRelease(Modifier),
    KeyPress(String),
    KeyRelease(String),
    Sleep(Duration),
    StdinText { delay: Duration },
}
```

### 2. Wayland Protocol Layer (`wayland.rs`)

**Responsibilities:**
- Wayland connection management
- Protocol object lifecycle
- Virtual keyboard protocol implementation
- Event dispatching and handling

**Key Components:**
- `WaylandState` - Central protocol state
- Protocol bindings generated from XML
- Event handlers for registry discovery
- Connection and roundtrip management

```rust
pub struct WaylandState {
    seat: Option<wl_seat::WlSeat>,
    manager: Option<ZwpVirtualKeyboardManagerV1>,
    keyboard: Option<ZwpVirtualKeyboardV1>,
    pub mod_state: u32,
}
```

### 3. Keymap Management (`keymap.rs`)

**Responsibilities:**
- Dynamic XKB keymap generation
- Unicode character to keysym mapping
- Keycode allocation and caching
- XKB file format generation

**Key Features:**
- On-demand keymap expansion
- Efficient character lookup caching
- XKB standard compliance
- Special character handling (newline, tab, escape)

```rust
pub struct KeymapBuilder {
    entries: Vec<KeymapEntry>,
    char_to_keycode: HashMap<char, u32>,
    symbol_to_keycode: HashMap<xkb::Keysym, u32>,
}
```

### 4. Command Execution Engine (`executor.rs`)

**Responsibilities:**
- Sequential command execution
- Protocol synchronization
- Timing control and delays
- UTF-8 stdin processing

**Execution Flow:**
1. Initialize keymap and upload to compositor
2. Process commands sequentially
3. Handle keymap updates dynamically
4. Manage modifier state
5. Clean up on completion

## Data Flow

### 1. Input Processing

```
Command Line → Args Parser → Command Generator → Command Queue
```

- CLI arguments are parsed using `clap` derive macros
- Arguments are converted to internal `Command` representations
- Commands are ordered for consistent execution

### 2. Wayland Connection

```
Environment → Connection → Registry → Protocol Discovery → Object Binding
```

- Connect to Wayland display (usually via `WAYLAND_DISPLAY`)
- Discover available protocols through registry
- Bind to required protocols (seat, virtual keyboard manager)
- Create virtual keyboard instance

### 3. Keymap Generation

```
Character/Key → XKB Lookup → Keycode Assignment → Keymap Generation → Upload
```

- Characters converted to XKB keysyms
- Keycodes allocated sequentially
- Complete XKB keymap generated in text format
- Keymap uploaded to compositor via file descriptor

### 4. Event Generation

```
Command → Keycode Resolution → Protocol Event → Compositor → Target App
```

- Commands resolved to specific keycodes
- Wayland keyboard events generated
- Events sent to compositor
- Compositor routes to focused application

## Key Design Decisions

### 1. Dynamic Keymap Generation

**Decision:** Generate keymaps on-demand rather than using static keymaps.

**Rationale:**
- Supports arbitrary Unicode characters
- Minimizes memory usage for simple use cases
- Provides flexibility for international text
- Avoids pre-defining large character sets

**Trade-offs:**
- Slight overhead for new characters
- Keymap regeneration on updates
- More complex implementation

### 2. Protocol-First Design

**Decision:** Implement Wayland virtual keyboard protocol directly rather than using higher-level libraries.

**Rationale:**
- Full control over protocol interaction
- Minimal dependencies and overhead
- Better error handling and debugging
- Educational value for protocol understanding

**Trade-offs:**
- More complex implementation
- Need to handle protocol edge cases
- Requires Wayland-specific knowledge

### 3. Synchronous Execution Model

**Decision:** Execute commands synchronously with explicit timing control.

**Rationale:**
- Predictable execution order
- Simple mental model for users
- Easy timing control with sleep commands
- Deterministic behavior for automation

**Trade-offs:**
- No parallelism for multiple operations
- Blocking on slow operations
- Less efficient for bulk operations

### 4. UTF-8 First Approach

**Decision:** Handle UTF-8 throughout the pipeline with proper boundary detection.

**Rationale:**
- International text support is essential
- Proper handling of multi-byte sequences
- Robust stdin processing
- Unicode-first design philosophy

**Trade-offs:**
- More complex string processing
- Additional validation overhead
- Handling of invalid sequences

## Protocol Implementation

### Virtual Keyboard Protocol Flow

1. **Discovery Phase:**
   ```
   Client → Registry → Seat Discovery
   Client → Registry → Virtual Keyboard Manager Discovery
   ```

2. **Initialization Phase:**
   ```
   Client → Manager → Create Virtual Keyboard
   Client → Keyboard → Upload Keymap
   ```

3. **Operation Phase:**
   ```
   Client → Keyboard → Set Modifiers
   Client → Keyboard → Key Press/Release Events
   ```

4. **Cleanup Phase:**
   ```
   Client → Keyboard → Release All Modifiers
   Client → Objects → Destroy/Cleanup
   ```

### Keymap Format

wrtype generates XKB keymaps in the standard text format:

```xkb
xkb_keymap {
    xkb_keycodes "(unnamed)" {
        minimum = 8;
        maximum = 16;
        <K1> = 9;
        <K2> = 10;
    };
    xkb_types "(unnamed)" { include "complete" };
    xkb_compatibility "(unnamed)" { include "complete" };
    xkb_symbols "(unnamed)" {
        key <K1> {[Return]};
        key <K2> {[space]};
    };
};
```

## Error Handling Strategy

### Layered Error Handling

1. **System Level:** Connection failures, protocol errors
2. **Application Level:** Invalid arguments, missing resources
3. **User Level:** Clear error messages with actionable advice

### Error Types

- **Protocol Errors:** Wayland connection, virtual keyboard not supported
- **Validation Errors:** Invalid key names, unknown modifiers
- **I/O Errors:** Stdin reading, file operations
- **Timing Errors:** Sleep interruption, timing precision

### Recovery Strategies

- **Graceful Degradation:** Continue processing where possible
- **Clean Cleanup:** Release modifiers and resources on exit
- **Clear Messaging:** Provide actionable error information

## Performance Characteristics

### Time Complexity
- **Keymap Lookup:** O(1) average for cached characters
- **Keymap Generation:** O(n) where n is number of unique characters
- **Command Processing:** O(m) where m is number of commands

### Space Complexity
- **Memory Usage:** O(k) where k is unique characters/keys used
- **Protocol Overhead:** Minimal per-event overhead
- **Keymap Size:** Grows linearly with character set

### Optimization Opportunities

1. **Keymap Batching:** Group character additions to reduce uploads
2. **Event Batching:** Combine multiple events in single roundtrip
3. **Caching:** Cache keymap generation results
4. **Streaming:** Process large stdin inputs in chunks

## Security Considerations

### Input Validation
- Validate all user inputs before processing
- Sanitize key names and modifier names
- Prevent injection attacks through careful parsing

### Protocol Security
- Use only documented Wayland protocols
- Validate all protocol responses
- Handle malformed compositor responses gracefully

### System Integration
- Respect compositor security policies
- Handle permission denials gracefully
- Avoid privilege escalation attempts

## Testing Strategy

### Unit Testing
- Individual component testing
- Mock Wayland protocols for testing
- Edge case validation

### Integration Testing
- Full pipeline testing
- Real protocol interaction
- Multi-compositor compatibility

### Property Testing
- Unicode character handling
- Timing precision validation
- Protocol state consistency

## Future Extensibility

### Planned Features
- Configuration file support
- Macro recording and playback
- Script execution capabilities
- GUI automation helpers

### Architecture Flexibility
- Plugin system for custom commands
- Multiple output formats (beyond Wayland)
- Advanced timing models
- Performance optimization hooks

This architecture provides a solid foundation for reliable, efficient, and extensible virtual keyboard functionality while maintaining simplicity and clarity in the codebase.