Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d1bc2a3
chore: update icons, integrate meson build
astraldev Jul 20, 2025
74cdfba
feat: update Flatpak configuration and add context menu actions
astraldev Jul 20, 2025
5b9e48c
chore: update meson files and assets
astraldev Jul 20, 2025
984cb3c
chore: update meson.build file
astraldev Jul 20, 2025
60557f0
chore: improve meson build
astraldev Jul 20, 2025
dd88f5b
chore: test meson build
astraldev Jul 20, 2025
b87a01a
fix: launch on GTK4/libadwaita and prune logic-gate dead code
astraldev Jun 13, 2026
acc8344
fix: restore libadwaita styling and repair property dialog, simulatio…
astraldev Jun 14, 2026
a0c0edc
fix: libadwaita styling, property dialog UX, and running-mode crashes
astraldev Jun 14, 2026
7daa9c6
feat: revamp component sidebar (search, categories, all-caps) and wir…
astraldev Jun 14, 2026
f23bbef
feat: preferences revamp, component-movement animation, viewport-size…
astraldev Jun 14, 2026
1d392de
build: fix launcher imports, version, app-id casing, meson portability
astraldev Jun 14, 2026
a078fb1
fix: latent migration bugs in save/export/alert/sidebar/timing paths
astraldev Jun 14, 2026
2a86e13
feat: revamp timing diagram dialog and draw area
astraldev Jun 14, 2026
f7b37cc
feat: add theming system with dynamic JSON theme pipeline
astraldev Jun 14, 2026
50270a6
docs: expand icon-creation plan and add delegation brief
astraldev Jun 14, 2026
1291611
fix: oscillator timing, gate sim safety, theme picker, dev-mode flag
astraldev Jun 14, 2026
14693f1
build: portable resource pipeline, dynamic dev gresource, CI tarball
astraldev Jun 14, 2026
c42b081
style: tidy build-script comments
astraldev Jun 14, 2026
80857e7
ci: resolve pygobject dependency and upgrade flatpak to gnome-48
astraldev Jun 14, 2026
774f6c0
ci: use correct package name python3-gobject-devel on Fedora
astraldev Jun 14, 2026
7f59f0f
ci: install python3-devel dependency in build pipeline
astraldev Jun 14, 2026
19e8654
ci: install desktop-file-utils and disable flatpak builder rofiles-fuse
astraldev Jun 14, 2026
13a0816
ci: restrict package builds to releases and add snap and deb workflows
astraldev Jun 14, 2026
56176d7
build: modernize CI runners, release-gate packaging, add Debian packa…
astraldev Jun 14, 2026
295e47c
perf: improvement of main page and timing running screen calculation
astraldev Jun 14, 2026
aa26482
perf: improvement of main page and timing running screen calculation
astraldev Jun 14, 2026
a3f99f6
perf: improve draw area performance and zoom responsiveness
astraldev Jun 14, 2026
b8c1ca2
chore: ui improvements for theming and consistency
astraldev Jun 14, 2026
58a2c8c
feat: improve toast management and bottom bar
astraldev Jun 14, 2026
54353a8
chore: project cleanup, remove orphaned files and improve property wi…
astraldev Jun 14, 2026
dc3e5a9
feat: update app id, and improve app bindings
astraldev Jun 14, 2026
fdcc7ae
feat: integrate themed component icon set and fix icon loading
astraldev Jun 15, 2026
8818c61
chore: asset updates
astraldev Jun 15, 2026
f9304cb
feat: improve animation computing on circuit manager + icon spec update
astraldev Jun 15, 2026
34454fe
feat: improve animation computing on circuit manager, and playback co…
astraldev Jun 15, 2026
8516b0c
docs: add preview gallery and demo video, refresh project docs
astraldev Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .agents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# `.agents/` — agent working docs for GGate

Index of the working docs and reference material agents use on GGate
(logic-circuit simulator, **GTK 4 + libadwaita**, heavy **Cairo** canvas).

## Directory map

- `TODO.md` — working backlog (P-levels; Done at the bottom).
- `plans/` — forward-looking implementation plans (icons).
- `skills/` — actionable how-to: `developing-gtk-apps.md` (architecture/plumbing),
`designing-gnome-ui.md` (HIG), `glc-format/SKILL.md` (authoring `.glc` circuits;
self-contained, portable to external models).
- `reference/` — `delegation-brief.md` (read first when delegating: repo facts,
conventions, verification) and `build-system-analysis.md` (build audit).
- `gtk4/` — raw GTK4/libadwaita/Pango/Gio/Cairo API docs by namespace; index at
`gtk4/README.md`.

## GTK4 documentation database — how to use

Scoped to the widgets/APIs this project actually uses, not the whole toolkit, so an
agent can continue UI work without re-deriving it from scratch.

1. **Architecture / plumbing question** (lifecycle, threading, GSettings, actions,
packaging, "app crashes/freezes") → `skills/developing-gtk-apps.md`.
2. **UI / widget choice / HIG / "which widget, how to lay it out"** →
`skills/designing-gnome-ui.md`.
3. **Exact API of a widget already chosen** (constructor, methods, signals, gotchas)
→ the relevant file in `gtk4/`. Start at `gtk4/README.md` for the index.

Always prefer these over guessing. For anything version-sensitive or not covered,
confirm against the canonical docs:

- Libadwaita 1.x: https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1-latest/
- GTK 4: https://docs.gtk.org/gtk4/
- PyGObject: https://api.pygobject.gnome.org/ • PyCairo: https://pycairo.readthedocs.io/

## Project context (why these widgets)

- **The canvas is the app.** `Gtk.DrawingArea` + Cairo draw every gate, wire, and the
new timing-waveform graph. `gtk4/drawing-cairo.md` is the most load-bearing file here.
- **Input = event controllers**, not legacy signals: `GestureClick`,
`EventControllerMotion/Key/Focus` drive placing/dragging/selecting components.
- **Dialogs are migrating to libadwaita**: the rewritten `PropertyWindow`
(`ggate/Components/Windows/Properties.py`) uses `Adw.Dialog` + boxed-list rows +
`Adw.Banner` for inline validation. See `gtk4/adwaita/`.
- **Text on canvas = Pango**, measured/rendered through Cairo. See `gtk4/pango/`.

## Layout

`gtk4/` holds the **raw canonical HTML reference pages** (one per class), fetched from
the official docs — read them directly. They are grouped by namespace:

| Path | Source | Pages |
|------|--------|-------|
| `gtk4/README.md` | (navigation index) widget → where used in GGate → which file | — |
| `gtk4/adwaita/` | libadwaita 1.x — gnome.pages.gitlab.gnome.org/libadwaita | 17: Dialog, Application(Window), Preferences{Page,Group}, EntryRow, SpinRow, ComboRow, SwitchRow, Banner, StatusPage, HeaderBar, AboutDialog, AlertDialog, ResponseAppearance, Toast, ToastOverlay |
| `gtk4/gtk/` | GTK 4 — docs.gtk.org/gtk4 | 35: DrawingArea, Box, Label, Image, ScrolledWindow, ListBox(Row), Frame, Paned, Button, MenuButton, ToggleButton, SpinButton, CheckButton, ComboBox(Text), Color/FontDialog(Button), PopoverMenu, Gesture/EventController*, FileDialog, FileFilter, StringList, ListStore, CellRendererText, Builder, Window, HeaderBar, ActionBar |
| `gtk4/pango/` | Pango — docs.gtk.org/Pango | 2: Layout, FontDescription |
| `gtk4/gio/` | GIO — docs.gtk.org/gio | 2: SimpleAction, ListStore |
| `gtk4/cairo/` | PyCairo — pycairo.readthedocs.io | 4: context, surfaces, patterns, matrix |

`skills/` holds three installable skills as authored guidance (not raw docs):

| File | Covers |
|------|--------|
| `skills/developing-gtk-apps.md` | App architecture, lifecycle, threading, GSettings, packaging |
| `skills/designing-gnome-ui.md` | GNOME HIG, widget selection, UI polish |
| `skills/glc-format/SKILL.md` | GGate GLC circuit file format specification and catalog |

> Pages are full HTML (nav chrome included) — read the class's *Constructors / Methods /
> Properties / Signals* sections. To refresh or add a class, curl the canonical URL, e.g.
> `curl -sL https://docs.gtk.org/gtk4/class.<Name>.html -o gtk4/gtk/<Name>.html`
> (libadwaita: `.../libadwaita/doc/1-latest/class.<Name>.html`).

## Cross-cutting rules (do not violate)

- **GTK is single-threaded.** Touch widgets only on the main thread; marshal with
`GLib.idle_add(...)`. (Cairo draw funcs already run on the main thread.)
- **GTK 4 has no `show_all()`** — widgets are visible by default; use `set_visible()`.
- **No `container.add()`** — use `box.append()`, `set_child()`, `Adw.PreferencesGroup.add()`.
- **Dialogs**: prefer `Adw.Dialog`/`Adw.AlertDialog` (adaptive, `.present(parent)`) over
`Gtk.Dialog`/`Gtk.MessageDialog` (deprecated in GTK 4.10).
- **File chooser**: prefer async `Gtk.FileDialog` (4.10+) over `Gtk.FileChooserDialog`.
115 changes: 115 additions & 0 deletions .agents/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# GGate — working backlog

Status legend: `[ ]` open · `[~]` in progress · `[x]` done. **(verify)** = confirm
against current code first. Owner model: Claude specs → agy implements → Claude reviews.
Companion docs: `reference/build-system-analysis.md`, `reference/delegation-brief.md`,
`plans/`, `skills/glc-format/SKILL.md`.

## P1 — polish

- [ ] **Guard against over-large circuits.** Warn (and optionally block) when loading a circuit
too large to handle, and warn when a save/compress or simulation will take too long, instead of
hanging/OOM-ing. (Run-time hang is mitigated by the non-blocking sim + the >15s log, but there's
no up-front guard.)
- [ ] Style: residual 2-vs-4-space indent, mixed quotes in older files (new work follows: double quotes, comments per the `comment-style` memory).

## Build & packaging

- [ ] **Flatpak** — decouple pip deps from network (`flatpak-pip-generator`) for offline build.
- [ ] **Snapcraft** — remove remote `curl|python3` scripts; drop hardcoded prefix.
- [ ] Relax `shapely` pin / pyproject cleanup (partly done — confirm).

## P3 — feature backlog

- [ ] Auto-scroll the timing diagram to follow the latest timestamp while running (deferred from
the timing plan §6 Q1).
- [ ] **Playback follow-ups (deferred).** Frame subsampling for very long timelines (so playback
holds the target duration instead of running long at the 16ms floor); optional per-session
speed control beyond the global `playback_duration` preference; a "Computing…" affordance for
pathological circuits whose up-front compute is slow.

## Inline TODOs

- [ ] `Managers/Alerts.py:8`, `MainFrame.py` — i18n/translations.
- [ ] `Managers/FileManager.py:104` — implement schematics export.
- [ ] `MainFrame.py` — toast on clipboard parse failure.
- [ ] `DrawArea.py:516` — optimize redraw.

## ✅ Done

Earlier work (app launches, dialogs migrated, sim/crash fixes) — see git history
`a0c0edc`…`a078fb1`. Recent (this development cycle):

- [x] **Animated simulation playback (record-then-play)** — replaced the throttle-the-engine
attempt with a clean two-phase model: `CircuitManager` computes the full timeline at engine
speed in non-blocking idle slices (`begin_compute`/`compute_slice`), then a new
`ggate/CircuitPlaybackAnimation.py` GObject paces playback over the recorded frames
(`apply_frame_at`), pacing to a target duration (`playback_duration` pref) clamped to
16–200ms/frame. State machine `computing→playing⇄paused→ended/idle` via `playback-state-changed`.
Non-animating circuits (no time evolution, e.g. no oscillator) skip playback and just show the
settled state. See `.agents/reviews/circuitmanager-sim-animation-review.md` for the rejected
first attempt.
- [x] **Floating playback control bar** (`ggate/PlaybackControls.py`) — OSD pill overlaid bottom-
centre of the canvas (DrawArea reworked to a `Gtk.Overlay` wrapping its scroller). Stop ·
Restart · Play/Pause │ seek scale · fixed-width sim-time readout. Shown only for animating
circuits, persists through the whole session, Stop ends the run via the header toggle.
- [x] **`playback_duration` preference** — new Simulation-page setting (`Preference.py`,
`Preferences.py`) controlling how long an animation takes to play back.
- [x] **Header simulation controls simplified to Play/Stop** — removed the redundant header Pause
button and the orphaned `pause_running_mode` path now that the floating bar owns transport.
- [x] **Live-edit recompute (switch/property desync fix)** — editing a property or toggling a
switch during a run now cancels playback and recomputes from t=0 via a shared
`MainFrame.recompute_simulation()`; switch toggles persist into their initial-state value so a
from-scratch recompute holds them.
- [x] **Icon system** (plan: `plans/icon-creation.md`) — hand-drawn component SVGs in two
variants (ANSI/IEC), gresource→freedesktop layout with aliases, `IconTheme.add_resource_path`
at startup, `ComponentView`/`MenuPopover` switched to icon-name lookups, `_get_icon_path`
deleted. Includes new themed 7-segment and LED icons.
- [x] **Fix gresource icon layout** — tidied the dev XML's double-"actions" nesting/misfiled
components into a clean freedesktop layout, dev + installed in sync.
- [x] **PIPO clock-bubble draw bug** — `PIPOShiftRegister.py` drew the clock trigger bubble at
the `CK` coordinate (`outpin_b + 40`) instead of `SL` (`outpin_b + 20`).
- [x] **Generate `config.py` via meson** (`configure_file`) instead of hardcoded VERSION/paths,
keeping the dev `run.py` path working.
- [x] **Desktop file + AppStream install via meson** — meson installs the renamed
desktop/metadata, not just legacy `setup.py`.
- [x] **Unify dev vs installed resource source** — dev XML generated by `run.py`, installed by
`resources.xml.in` + meson glob.
- [x] **Timing diagram width cap warning** — added a warning banner (`Adw.Banner`) in the timing graph dialog to notify the user when the diagram width is capped at Cairo's limit.
- [x] **First-paint centering decoupled** — fixed `ggate/DrawArea.py` and `ggate/MainFrame.py` so that initial canvas viewport centering is always performed on file/buffer load, even when the resize auto-centering preference is disabled.
- [x] **translator-credits & header cleanups** — cleaned up the commented-out translator-credits block in `MainFrame.py` and removed the stale `indent-tabs-mode` editor directives from 8 Python files.

- [x] **Timing diagram visual polish** — increased waveform amplitude within each row (from 20px to 28px), auto-fit/default the time range to the actual extent of simulation history, calculated a saner default zoom for high-frequency signals to avoid picket-fences, and fixed dead vertical space by drawing backgrounds down the full allocated height.

- [x] **Property window widget reuse & leak fix** — optimized `PropertyWindow` (`ggate/Components/Windows/Properties.py`) to build its toolbar view, header bar, and banner once on initialization and reuse them, avoiding widget leaks. Also removed the redundant section header from Seven Segment LED properties.

- [x] **Remove GTK3 leftovers & dead exporter stub** — deleted dead GTK3 leftover files `ggate/TimingDiagramWindow.py` and `ggate/DiagramArea.py`, and the dead exporter stub `ggate/Components/Managers/Exporter.py`.

- [x] **Header bar migrated to Adw.HeaderBar** — replaced Gtk.HeaderBar with Adw.HeaderBar for standard Adwaita layout, positioning menu buttons and simulation controls on the right.
- [x] **AlertDialogs duplicate response fixed** — refactored class to dynamically instantiate Adw.AlertDialog instead of subclassing it to avoid registering same response IDs multiple times.
- [x] **Theme Light/Dark Variants** — renamed existing dark themes (Frappé, Mocha, Space) to (Dark) and created new (Light) variant JSON files: FrappeLight.json (using Catppuccin Latte), MochaLight.json (using Catppuccin Latte/Light variant), and SpaceLight.json (using Space Light variant).
- [x] **Zoom limit restrictions** — restricted zoom level range on the canvas to between 0.5 and 20.0 (in ggate/DrawArea.py).
- [x] **GLC file serialization and parsing zoom/positions** — added a `meta` block to output and restore the current canvas zoom level on load, and cleaned up coordinate serialization/parsing using comprehensions and float string handling.
- [x] **Preferences font picker** — completed typography section with monospace font filtering.
- [x] **Timing diagram revamp** — `Display.py` (`Adw.Dialog` + `ToolbarView`, scale/range/
save toolbar) and `Diagram.py` (synced scrolls, pure `set_draw_func` rendering, gesture
scrubbing, empty-history placeholder) rewritten; renders waveforms theme-aware.
- [x] **Theming system** — built-in themes (Classic/Space/Frappé/Mocha) as JSON in
`data/themes/`, globbed into the gresource and discovered dynamically at runtime;
`Themes.py` registry + `apply_theme`/`apply_chrome`; theme picker in Preferences.
- [x] **Preferences revamp** — migrated to `Adw.PreferencesDialog` with multiple pages
(Appearance/Theme/Simulation/Canvas) and Adw rows.
- [x] **Theme picker fixed** — model rebuilt from registry (chevron shows), selection no
longer reverts to Custom.
- [x] **Oscillator timing + gate sim safety** — `analyze_logic` runs at run start so
oscillators populate history; gates compute via `all/any/sum` (no IndexError on
unconnected pins); `.glc` property types load correctly (`parse_section`).
- [x] **Dev gresource never stale** — `run.py` regenerates + compiles `dev-resources.gresource`
from the asset dirs each launch.
- [x] **Build portability** — non-portable `find|sed`/inline-python globbing → shell helpers;
`prefix` shadowing fixed; `RUNNING_FROM_SOURCE` replaces vague `DEV_MODE`.
- [x] **CI** — Fedora-container GitHub Actions workflow produces a `meson dist` `tar.gz`.
- [x] **About dialog wired** (`on_action_about_pressed` → `AboutGGate.create().present`).
- [x] **Version unified** — `config.py`/`__init__.py`/`pyproject`/`meson` all `5.0.0`.
- [x] **bin/ggate.in** imports + version string correct.
- [x] **`.glc` format spec** documented (`skills/glc-format/SKILL.md`).
Loading