# GEMINI.md

## Project Overview

This project is a `gtklock` module named `ahfail`, written in Rust (using `gtk-rs`) with a Meson build system.

The module listens for failed unlock attempts (`PW_FAILURE`) in `gtklock`. Upon failure, it:
1.  Spawns a looping "Nedry" sprite animation at a random screen location.
2.  Plays an audio clip ("ah ah ah, you didn't say the magic word").
3.  Avoids placing sprites in a user-configurable "deadzone".

All assets (images and audio) are compiled into the module binary as GResources.

## Build Architecture

*   **Meson:** The primary build system. It handles:
    *   Compiling GResources (`assets/ahfail.gresource.xml`).
    *   Invoking Cargo to build the Rust code as a static library (`libahfail_module.a`).
    *   Linking the Rust static library, GResources, and C dependencies into the final shared object (`ahfail-module.so`).
*   **Cargo:** Handles the Rust source code, dependencies (`gtk`, `gdk`, `gstreamer`), and tests.

## Key Files

*   `src/lib.rs`: FFI entry points (`on_activation`, `on_window_create`, etc.) exported to C.
*   `src/handler.rs`: Main logic for sprite placement and audio playback.
*   `src/config.rs`: Argument parsing logic.
*   `tests/ahfail_tests.rs`: Comprehensive integration tests mocking `gtklock` behavior.
*   `meson.build`: Build definition bridging C and Rust.

## Building and Running

### Prerequisites
*   Meson, Ninja, Rust (Cargo)
*   `gtk3` development headers
*   `gstreamer` + `gst-plugins-base` + `gst-plugins-good` (runtime)

### Commands
```bash
# Setup
meson setup builddir

# Build
meson compile -C builddir

# Test (Rust logic)
cargo test

# Run (Manual test)
gtklock -d -m builddir/ahfail-module.so -- --deadzone=X,Y,W,H
```

## Development Conventions

*   **Safety:** Use `WindowContext` wrappers in `src/context.rs` to handle unsafe `Window` pointers.
*   **State:** `MODULE_STATE` (thread-local) holds global config/assets. `WindowData` (heap-allocated) holds per-window sprites and players.
*   **Tests:** `tests/ahfail_tests.rs` contains integration tests that mock `gtklock` structures. Run with `cargo test`.
