Files
nomines/AGENTS.md
T
bernardo 97565e415d Add flatpak build plumbing
- io.github.bemagri.nomines.yml: builds libsigc++/glibmm/cairomm/pangomm/gtkmm
  from tarballs against the GNOME 46 runtime, then the app from the v1.0.0 tag
- Icon: app-id-named PNGs (128/512) for flatpak export, svg kept for native
  installs; desktop file Icon updated
- README/AGENTS.md: flatpak build instructions and version traps
2026-08-01 15:34:28 +01:00

44 lines
5.0 KiB
Markdown

# AGENTS.md
GTK4/gtkmm4 Minesweeper clone ("NoMines") in C++20, built with Meson. ~800 lines total.
## Build & run
```bash
meson setup build # or reuse existing build/
meson compile -C build
./build/nomines
```
- Dev deps come from the Nix flake via direnv (`.envrc` uses `use flake`); `nix develop` works standalone.
- Alternative: `nix build` / `nix run`.
- No unit tests; two optional release-validation tests (desktop file + AppStream metainfo via `desktop-file-validate`/`appstreamcli`) are auto-added when those tools exist.
- `build/compile_commands.json` exists for clangd (it's gitignored, regenerate with `meson setup --wipe build` if stale).
- WARNING: flake builds only see git-tracked files. New source files must be `git add`ed before `nix build` works.
## Architecture
- `src/minefield.*` — pure game logic, no GTK: `Minefield` (board state, flag counting, chording), `Cell` bitfield, `GameDifficulty` presets, `GameState` enum.
- `src/board_widget.*``Gtk::DrawingArea`; all rendering is hand-drawn Cairo primitives (draw_cell/draw_digit/draw_flag/draw_bomb), input via `Gtk::GestureClick` + `EventControllerMotion`, confetti particle animation on win (frame-rate independent via `Gdk::FrameClock`).
- `src/window.*``Gtk::ApplicationWindow` with HeaderBar, difficulty popover (radio-style `CheckButton`s), leaderboard popover, timer; owns the `shared_ptr<Minefield>` and swaps it on new game. Keyboard shortcuts via `Gtk::EventControllerKey` (R/Ctrl+N new game, 1-4 difficulties, L leaderboard).
- `src/leaderboard.*` — persistent best times per difficulty via `Glib::KeyFile` at `~/.config/nomines/leaderboard.ini` (recorded on win, shown in a header-bar popover; falls back to the pre-1.0 `~/.config/minesweeper/` path for migration). NOTE: uses the glibmm 2.80 refcounted `KeyFile::create()` API and gtkmm 4.14 `CheckButton` (a `Widget`+`Actionable`, not a `Button` — use `signal_toggled()` + `get_active()`, and `set_group(CheckButton&)`).
- glibmm 2.80 quirk: `SignalProxy<R(T...)>::connect()` (non-void return signals like `signal_key_pressed`) requires the `after` bool explicitly — `connect(slot, false)`. Void signals default it to true.
- `src/main.cpp` — single `Gtk::Application` (`io.github.bemagri.nomines`); `make_window_and_run<MainWindow>`.
## Release
- Version `1.0.0` is stamped in FOUR places: `meson.build`, `flake.nix`, `default.nix`, and the `<releases>` entry in `resources/io.github.bemagri.nomines.metainfo.xml`. Bump all four together.
- Release sanity: `nix build .` (validates the flake), `desktop-file-validate` + `appstreamcli validate --no-net` on the resources (wired up as meson tests).
- The metainfo screenshot URL points at `raw.githubusercontent.com/bemagri/nomines/main/...` — it 404s until the repo is published; replace if the repo moves.
- Flatpak: `io.github.bemagri.nomines.yml` builds libsigc++/glibmm/cairomm/pangomm/gtkmm from tarballs against the GNOME 46 runtime (matches the gtkmm 4.14/glib 2.80 stack we develop against), then the app from the `v1.0.0` git tag. The pinned `commit:` must match the pushed tag. The leaderboard needs the `--filesystem=xdg-config/nomines:create` finish-arg — don't drop it. Local builds land in `.flatpak-builder/` (gitignored); `flatpak-builder --user --install --force-clean build-flatpak io.github.bemagri.nomines.yml`.
- Flatpak module version traps (all verified by building): gtkmm 4.14 needs pangomm >= 2.50 (which still installs `pangomm-2.48.pc`; 2.48.x is too old), and cairomm tarballs live on `cairographics.org/releases`, not download.gnome.org. `appstream-compose: false` is set in the manifest because flatpak-builder's compose fetches the (still-404) metainfo screenshot URL — remove it once the repo is public. Flatpak's icon validation can't decode SVGs, so PNG icons (128/512) are installed under the app-id name and the svg is cleanup-removed; keep that convention.
## Gotchas
- `resources/gresource.xml` + the `gnome.compile_resources` step in `meson.build` compile unused code: the app never loads these SVGs/textures (the `confetti.png` is also unused). All art is Cairo-drawn. Don't extend the GResource to implement visual features; draw with Cairo instead.
- README's feature list is mostly accurate but not trustworthy in detail; verify against code. (An older `leaderboard.txt` CSV may linger in `~/.config/minesweeper/` from a previous experiment — the app now uses `~/.config/nomines/leaderboard.ini`.)
- Code style: snake_case methods/fields, trailing `_` on private members, `#pragma once`, nested-struct headers. C++20 stdlib only, no third-party libs beyond gtkmm/sigc++.
- Board colors are theme-aware: `BoardWidget::resolve_palette()` maps GTK CSS named colors (`theme_bg_color`, `theme_base_color`, ...) to a light/dark palette each draw. Don't hardcode light grays in `draw_*` helpers; thread the `Palette` through instead.
- Meson source list is explicit in `meson.build` — new source files must be added there.
- `.direnv/` and `build*/` are gitignored; flake builds require files to be committed/tracked.